diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..9fd870b859 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +*.log +cmake_targets/log/ +cmake_targets/ran_build/ +common/utils/T/T_IDs.h +common/utils/T/T_messages.txt.h +common/utils/T/genids +common/utils/T/genids.o +targets/bin/ diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 7e9e3800db..ff661543c0 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -35,6 +35,13 @@ def doFlexranCtrlTest = false // Location of the executor node def nodeExecutor = params.nodeExecutor +// VM Lockable resources +def vmResource = params.vmLockableResource + +// Tags to shorten pipeline duration +def doMandatoryTests = false +def doFullTestsuite = false + pipeline { agent { label nodeExecutor @@ -43,31 +50,6 @@ 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 L1-sim", - "Test RF-sim", - "Test L2-sim", - "Test-Mono-FDD-Band7", - "Test-Mono-TDD-Band40", - "Test-IF4p5-FDD-Band7", - "Test-IF4p5-TDD-Band40", - "Test-Mono-FDD-Band13-LTE-M", - "Test-IF4p5-TDD-Band38-Multi-RRU", - "Test-eNB-OAI-UE-FDD-Band7", - "Test-Mono-FDD-Band13-X2-HO", - "Test-TDD-Band78-gNB-NR-UE", - "Test-OCP-FDD-Band7" - ]) ansiColor('xterm') } @@ -90,6 +72,33 @@ pipeline { if (fileExists("flexran")) { sh "rm -Rf flexran > /dev/null 2>&1" } + + echo '\u2705 \u001B[32mVerify Labels\u001B[0m' + if ("MERGE".equals(env.gitlabActionType)) { + LABEL_CHECK = sh returnStdout: true, script: 'ci-scripts/checkGitLabMergeRequestLabels.sh --mr-id ' + env.gitlabMergeRequestIid + LABEL_CHECK = LABEL_CHECK.trim() + if (LABEL_CHECK == 'NONE') { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Your merge request has none of the mandatory labels:\n\n" + message += " - BUILD-ONLY\n" + message += " - 4G-LTE\n" + message += " - 5G-NR\n" + message += " - CI\n\n" + message += "Not performing CI due to lack of labels" + addGitLabMRComment comment: message + error('Not performing CI due to lack of labels') + } else if (LABEL_CHECK == 'FULL') { + doMandatoryTests = true + doFullTestsuite = true + } else if (LABEL_CHECK == 'SHORTEN-5G') { + doMandatoryTests = true + } else { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): We will perform only build stages on your Merge Request" + addGitLabMRComment comment: message + } + } else { + doMandatoryTests = true + doFullTestsuite = true + } } } } @@ -132,7 +141,7 @@ pipeline { // For the moment, there is no fail criteria. Just a notification of number of files that do not follow sh "./ci-scripts/checkCodingFormattingRules.sh" } - if (doFlexranCtrlTest) { + if (doFlexranCtrlTest && doMandatoryTests) { sh "mkdir flexran" dir ('flexran') { withCredentials([ @@ -159,65 +168,81 @@ pipeline { stage ("Start VM -- basic-sim") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- gnb-usrp") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- nr-ue-usrp") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- enb-usrp") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- phy-sim") { steps { + lock (vmResource) { timeout (time: 5, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- enb-ethernet") { steps { - timeout (time: 5, unit: 'MINUTES') { + lock (vmResource) { + timeout (time: 7, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- ue-ethernet") { steps { - timeout (time: 5, unit: 'MINUTES') { + lock (vmResource) { + timeout (time: 7, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } stage ("Start VM -- cppcheck") { steps { - timeout (time: 5, unit: 'MINUTES') { + lock (vmResource) { + timeout (time: 7, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } + } } } @@ -288,11 +313,14 @@ pipeline { } stage ("Build UE-ethernet") { steps { + // This is typically the last one to finish. + lock (vmResource) { gitlabCommitStatus(name: "Build UE-ethernet") { timeout (time: 20, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } + } } } } @@ -353,7 +381,11 @@ pipeline { stage ("VM-based tests") { stages { stage ("Test physical simulators") { + when { + expression {doMandatoryTests} + } steps { + lock (vmResource) { script { timeout (time: 90, unit: 'MINUTES') { try { @@ -365,13 +397,15 @@ pipeline { } } } + } } } stage ("Build Flexran Controller") { when { - expression {doFlexranCtrlTest} + expression {doFlexranCtrlTest && doMandatoryTests} } steps { + lock (vmResource) { script { timeout (time: 20, unit: 'MINUTES') { try { @@ -381,10 +415,15 @@ pipeline { } } } + } } } stage ("Test basic simulator") { + when { + expression {doMandatoryTests} + } steps { + lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -396,10 +435,15 @@ pipeline { } } } + } } } stage ("Test L1 simulator") { + when { + expression {doMandatoryTests} + } steps { + lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -411,12 +455,17 @@ pipeline { } } } + } } } stage ("Test RF simulator") { + when { + expression {doMandatoryTests} + } steps { + lock (vmResource) { script { - timeout (time: 30, unit: 'MINUTES') { + timeout (time: 40, unit: 'MINUTES') { try { gitlabCommitStatus(name: "Test RF-sim") { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" @@ -426,10 +475,15 @@ pipeline { } } } + } } } stage ("Test L2 simulator") { + when { + expression {doFullTestsuite} + } steps { + lock (vmResource) { script { timeout (time: 30, unit: 'MINUTES') { try { @@ -441,16 +495,25 @@ pipeline { } } } + } } } stage ("Destroy all Virtual Machines") { + when { + expression {doMandatoryTests} + } steps { + lock (vmResource) { sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } } } } } stage ("Test MONOLITHIC - FDD - Band 7 - B210") { + when { + expression {doFullTestsuite} + } steps { script { triggerSlaveJob ('eNB-CI-FDD-Band7-B210', 'Test-Mono-FDD-Band7') @@ -470,6 +533,9 @@ pipeline { } } stage ("Test MONOLITHIC - TDD - Band 40 - B210") { + when { + expression {doFullTestsuite} + } steps { script { triggerSlaveJob ('eNB-CI-TDD-Band40-B210', 'Test-Mono-TDD-Band40') @@ -489,6 +555,9 @@ pipeline { } } stage ("Test IF4p5 - FDD - Band 7 - B210") { + when { + expression {doFullTestsuite} + } steps { script { sh "sleep 60" @@ -509,6 +578,9 @@ pipeline { } } stage ("Test IF4p5 - TDD - Band 40 - B210") { + when { + expression {doFullTestsuite} + } steps { script { sh "sleep 60" @@ -529,6 +601,9 @@ pipeline { } } stage ("Test MONOLITHIC - FDD - Band 13 - B210") { + when { + expression {doFullTestsuite} + } steps { script { sh "sleep 60" @@ -549,6 +624,9 @@ pipeline { } } stage ("Test X2 Handover - FDD - Band 13 - B210") { + when { + expression {doFullTestsuite} + } steps { script { sh "sleep 60" @@ -569,6 +647,9 @@ pipeline { } } stage ("Test IF4p5 - TDD - Band 38 - B210 - MultiRRU") { + when { + expression {doFullTestsuite} + } steps { script { triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band38-MultiRRU-B210', 'Test-IF4p5-TDD-Band38-Multi-RRU') @@ -588,6 +669,9 @@ pipeline { } } stage ("Test OAI UE - FDD - Band 20 - B200") { + when { + expression {doFullTestsuite} + } steps { script { triggerSlaveJobNoGitLab ('UE-CI-FDD-Band20-B200') @@ -607,6 +691,9 @@ pipeline { } } stage ("Test OAI UE - OAI eNB - FDD - Band 7 - B200") { + when { + expression {doFullTestsuite} + } steps { script { // Delayed trigger on slave job, so it is always the last one to run @@ -628,6 +715,9 @@ pipeline { } } stage ("Test OAI NR UE - OAI gNB - TDD - Band 78 - N300") { + when { + expression {doMandatoryTests} + } steps { script { triggerSlaveJob ('gNB-nrUE-MONO-TDD-Band78-N300', 'Test-TDD-Band78-gNB-NR-UE') @@ -647,6 +737,9 @@ pipeline { } } stage ("Test OAI OCP-eNB - FDD - Band 7 - B210") { + when { + expression {doFullTestsuite} + } steps { script { triggerSlaveJob ('OCPeNB-FDD-Band7-B210', 'Test-OCP-FDD-Band7') @@ -669,6 +762,7 @@ pipeline { post { always { script { + if (doMandatoryTests) { dir ('archives') { sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi" } @@ -684,6 +778,7 @@ pipeline { archiveArtifacts artifacts: 'test_simulator_results.html' } } + } } } } diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran index 15ad0379af..c3323f792d 100644 --- a/ci-scripts/Jenkinsfile-tmp-full-ran +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -266,6 +266,42 @@ pipeline { } stage('Log Collection') { parallel { + stage('Log Collection (eNB - Build)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (eNB - Build)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (eNB - Build)\u001B[0m' + sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "build.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (OAI UE - Build)') { + steps { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Build)\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=LogCollectBuild --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (UE - Build)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("build.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "build.log.${env.BUILD_ID}.zip" + } + } + } + } stage('Log Collection (eNB - Run)') { steps { withCredentials([ diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py index 84b3a84514..248e873cdd 100644 --- a/ci-scripts/args_parse.py +++ b/ci-scripts/args_parse.py @@ -41,7 +41,7 @@ import constants as CONST #----------------------------------------------------------- -def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): +def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP): py_param_file_present = False @@ -79,6 +79,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): RAN.ranRepository=matchReg.group(1) HTML.ranRepository=matchReg.group(1) ldpc.ranRepository=matchReg.group(1) + CONTAINERS.ranRepository=matchReg.group(1) elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) @@ -90,6 +91,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): CiTestObj.ranAllowMerge = True RAN.ranAllowMerge=True HTML.ranAllowMerge=True + CONTAINERS.ranAllowMerge=True elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) @@ -99,6 +101,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): RAN.ranBranch=matchReg.group(1) HTML.ranBranch=matchReg.group(1) ldpc.ranBranch=matchReg.group(1) + CONTAINERS.ranBranch=matchReg.group(1) elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) @@ -108,6 +111,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): RAN.ranCommitID=matchReg.group(1) HTML.ranCommitID=matchReg.group(1) ldpc.ranCommitID=matchReg.group(1) + CONTAINERS.ranCommitID=matchReg.group(1) elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) @@ -117,50 +121,63 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): RAN.ranTargetBranch=matchReg.group(1) HTML.ranTargetBranch=matchReg.group(1) ldpc.ranTargetBranch=matchReg.group(1) + CONTAINERS.ranTargetBranch=matchReg.group(1) elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) RAN.eNBIPAddress=matchReg.group(1) ldpc.eNBIpAddr=matchReg.group(1) + CONTAINERS.eNBIPAddress=matchReg.group(1) elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) RAN.eNB1IPAddress=matchReg.group(1) + CONTAINERS.eNB1IPAddress=matchReg.group(1) elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) RAN.eNB2IPAddress=matchReg.group(1) + CONTAINERS.eNB2IPAddress=matchReg.group(1) elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) RAN.eNBUserName=matchReg.group(1) ldpc.eNBUserName=matchReg.group(1) + CONTAINERS.eNBUserName=matchReg.group(1) elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) RAN.eNB1UserName=matchReg.group(1) + CONTAINERS.eNB1UserName=matchReg.group(1) elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) RAN.eNB2UserName=matchReg.group(1) + CONTAINERS.eNB2UserName=matchReg.group(1) elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) RAN.eNBPassword=matchReg.group(1) ldpc.eNBPassWord=matchReg.group(1) + CONTAINERS.eNBPassword=matchReg.group(1) elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) RAN.eNB1Password=matchReg.group(1) + CONTAINERS.eNB1Password=matchReg.group(1) elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) RAN.eNB2Password=matchReg.group(1) + CONTAINERS.eNB2Password=matchReg.group(1) elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) RAN.eNBSourceCodePath=matchReg.group(1) ldpc.eNBSourceCodePath=matchReg.group(1) + CONTAINERS.eNBSourceCodePath=matchReg.group(1) elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) RAN.eNB1SourceCodePath=matchReg.group(1) + CONTAINERS.eNB1SourceCodePath=matchReg.group(1) elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) RAN.eNB2SourceCodePath=matchReg.group(1) + CONTAINERS.eNB2SourceCodePath=matchReg.group(1) elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) EPC.IPAddress=matchReg.group(1) diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 72fa29aa39..861cab0782 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -178,6 +178,8 @@ function build_on_vm { echo "mkdir -p cmake_targets/log" >> $VM_CMDS echo "chmod 777 cmake_targets/log" >> $VM_CMDS echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS + # Patching the pistache build for Xenial (cmake too old for new commits) + echo "sed -i -e 's@cd pistache@cd pistache \&\& git checkout -f 9a65f40975fafca5bb5370ba6d0d00f42cbc4356@' ./tools/install_dependencies" >> $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 diff --git a/ci-scripts/build_fr1_from_yaml.py b/ci-scripts/build_fr1_from_yaml.py new file mode 100755 index 0000000000..a5492df6f6 --- /dev/null +++ b/ci-scripts/build_fr1_from_yaml.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Tue Jul 7 23:04:51 2020 + +@author: hardy +""" + + + +import yaml +import sys +import subprocess + + + +def main(): + f_yaml=sys.argv[1] + f_sh=sys.argv[2] + #filename='py_params_template.yaml' + with open(f_yaml,'r') as file: + # The FullLoader parameter handles the conversion from YAML + # scalar values to Python the dictionary format + print('Loading '+f_yaml) + params = yaml.load(file,Loader=yaml.FullLoader) + + + with open(f_sh,'w') as f: + f.write('#!/bin/sh\n') + for i in range (0, len(params['steps'])): + step=params['steps'][i].split(',') + mode=step[0] + f_xml=step[1] + line='python3 main.py ' + \ + '--mode='+ mode + ' ' + \ + '--ranRepository=' + params['ranRepository'] + ' ' + \ + '--ranBranch=' + params['ranBranch'] + ' ' + \ + '--ranCommitID=' + params['ranCommitID'] + ' ' + \ + '--ranAllowMerge=' + params['ranAllowMerge'] + ' ' + \ + '--ranTargetBranch=' + params['ranTargetBranch'] + ' ' + \ + \ + '--ADBIPAddress=' + params['ADB']['ADBIPAddress'] + ' ' + \ + '--ADBUserName=' + params['ADB']['ADBUserName'] + ' ' + \ + '--ADBPassword=' + params['ADB']['ADBPassword'] + ' ' + \ + \ + '--UEIPAddress=' + params['UE']['UEIPAddress'] + ' ' + \ + '--UEUserName=' + params['UE']['UEUserName'] + ' ' + \ + '--UEPassword=' + params['UE']['UEPassword'] + ' ' + \ + '--UESourceCodePath=' + params['UE']['UESourceCodePath'] + ' ' + \ + \ + '--EPCIPAddress=' + params['EPC']['EPCIPAddress'] + ' ' + \ + '--EPCUserName=' + params['EPC']['EPCUserName'] + ' ' + \ + '--EPCPassword=' + params['EPC']['EPCPassword'] + ' ' + \ + '--EPCSourceCodePath=' + params['EPC']['EPCSourceCodePath'] + ' ' + \ + '--EPCType=' + params['EPC']['EPCType'] + ' ' + \ + \ + '--eNBIPAddress=' + params['RAN'][0]['eNBIPAddress'] + ' ' + \ + '--eNBUserName=' + params['RAN'][0]['eNBUserName'] + ' ' + \ + '--eNBPassword=' + params['RAN'][0]['eNBPassword'] + ' ' + \ + '--eNBSourceCodePath=' + params['RAN'][0]['eNBSourceCodePath'] + ' ' + \ + \ + '--eNB1IPAddress=' + params['RAN'][1]['eNB1IPAddress'] + ' ' + \ + '--eNB1UserName=' + params['RAN'][1]['eNB1UserName'] + ' ' + \ + '--eNB1Password=' + params['RAN'][1]['eNB1Password'] + ' ' + \ + '--eNB1SourceCodePath=' + params['RAN'][1]['eNB1SourceCodePath'] + ' ' + if mode!="InitiateHtml": + line+='--XMLTestFile=' + f_xml + #if mode is InitiateHTML we have a special processing to mention all xml files from the list + #loop starting at 1 to avoid the xml file mentioned with InitiateHtml in yaml file (file is none) + else: + for i in range (1, len(params['steps'])): + step=params['steps'][i].split(',') + f_xml=step[1] + line+='--XMLTestFile=' + f_xml+' ' + line+='\n' + print(line) + f.write(line) + subprocess.call(['chmod','777',f_sh]) + +if __name__ == "__main__": + main() + + diff --git a/ci-scripts/build_fr1_template.yaml b/ci-scripts/build_fr1_template.yaml new file mode 100755 index 0000000000..2a8f9cc6a0 --- /dev/null +++ b/ci-scripts/build_fr1_template.yaml @@ -0,0 +1,46 @@ + +ranRepository : https://gitlab.eurecom.fr/oai/openairinterface5g.git +ranBranch : BRANCH_NAME +ranCommitID : COMMIT_ID +ranAllowMerge : 'true' +ranTargetBranch : develop + +steps: + - InitiateHtml,none + - TesteNB,xml_files/fr1_multi_node_build.xml + - TesteNB,xml_files/fr1_epc_start.xml + - TesteNB,xml_files/fr1_ran_ue_base.xml #ue toggle, nodes initialize, ue toggle, ping, nodes terminate + - TesteNB,xml_files/fr1_epc_closure.xml + + +ADB: #on Caracal + ADBIPAddress : 192.168.18.196 + ADBUserName : oaici + ADBPassword : KkexF6CErOi1fNuebCPsuIVK + +RAN: + - eNBIPAddress : 192.168.18.199 #eNB on Minimassive + eNBUserName : oaicicd + eNBPassword : HzB*nkryaITdVd08TKlT#2Z5a!7M#~qn + eNBSourceCodePath : /tmp/CI-FR1-eNB + - eNB1IPAddress : 192.168.18.198 #gNB on Mozart + eNB1UserName : oaicicd + eNB1Password : 7zkDOFgh@w3HvRBMPTMh@BAx + eNB1SourceCodePath : /tmp/CI-FR1-gNB + + +EPC: #on Nikaia + EPCIPAddress : 192.168.18.99 + EPCUserName : nikaia + EPCPassword : linux + EPCSourceCodePath : /tmp/CI-FR1-EPC + EPCType : ltebox + + +UE: + UEIPAddress : none + UEUserName : none + UEPassword : none + UESourceCodePath : none + + diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index d47b90a9dd..3a2fcbb02c 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -59,7 +59,7 @@ if [ $# -eq 0 ] then echo " ---- Checking the whole repository ----" echo "" - NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted ` + NB_FILES_TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt --recursive *.c *.h | grep -c Formatted || true` echo "Nb Files that do NOT follow OAI rules: $NB_FILES_TO_FORMAT" echo $NB_FILES_TO_FORMAT > ./oai_rules_result.txt @@ -67,17 +67,17 @@ then awk '/#[ \t]*ifndef/ { gsub("^.*ifndef *",""); if (names[$1]!="") print "files with same {define ", FILENAME, names[$1]; names[$1]=FILENAME } /#[ \t]*define/ { gsub("^.*define *",""); if(names[$1]!=FILENAME) print "error in declaration", FILENAME, $1, names[$1]; nextfile }' `find openair* common targets executables -name *.h |grep -v LFDS` > header-files-w-incorrect-define.txt # Testing if explicit GNU GPL license banner - egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . > files-w-gnu-gpl-license-banner.txt + egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "General Public License" . | egrep -v "openair3/NAS/COMMON/milenage.h" > files-w-gnu-gpl-license-banner.txt # Looking at exotic/suspect banner LIST_OF_FILES_W_BANNER=`egrep -irl --exclude-dir=.git --include=*.cpp --include=*.c --include=*.h "Copyright|copyleft" .` if [ -f ./files-w-suspect-banner.txt ]; then rm -f ./files-w-suspect-banner.txt; fi for FILE in $LIST_OF_FILES_W_BANNER do - IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` - IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` + IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` + IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE || true` + IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] @@ -178,7 +178,7 @@ do EXT="${filename##*.}" if [ $EXT = "c" ] || [ $EXT = "h" ] || [ $EXT = "cpp" ] || [ $EXT = "hpp" ] then - TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted ` + TO_FORMAT=`astyle --dry-run --options=ci-scripts/astyle-options.txt $FULLFILE | grep -c Formatted || true` NB_TO_FORMAT=$((NB_TO_FORMAT + TO_FORMAT)) if [ $TO_FORMAT -ne 0 ] then @@ -186,15 +186,19 @@ do echo $FULLFILE >> ./oai_rules_result_list.txt fi # Testing if explicit GNU GPL license banner - egrep -i "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt + GNU_EXCEPTION=`echo $FULLFILE | egrep -c "openair3/NAS/COMMON/milenage.h" || true` + if [ $GNU_EXCEPTION -eq 0 ] + then + egrep -il "General Public License" $FULLFILE >> files-w-gnu-gpl-license-banner.txt + fi # Looking at exotic/suspect banner - IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE` + IS_BANNER=`egrep -i -c "Copyright|copyleft" $FULLFILE || true` if [ $IS_BANNER -ne 0 ] then - IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` - IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE` - IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` + IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` + IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE || true` + IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_|openair3/NAS/COMMON/milenage.h" || true` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] diff --git a/ci-scripts/checkGitLabMergeRequestLabels.sh b/ci-scripts/checkGitLabMergeRequestLabels.sh new file mode 100755 index 0000000000..7e4ea1c7de --- /dev/null +++ b/ci-scripts/checkGitLabMergeRequestLabels.sh @@ -0,0 +1,108 @@ +#!/bin/bash +#/* +# * 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 +# */ + +function usage { + echo "OAI GitLab merge request applying script" + echo " Original Author: Raphael Defosseux" + echo "" + echo "Usage:" + echo "------" + echo "" + echo " checkGitLabMergeRequestLabels.sh [OPTIONS]" + echo "" + echo "Options:" + echo "------------------" + echo "" + echo " --mr-id ####" + echo " Specify the ID of the merge request." + echo "" + echo " --help OR -h" + echo " Print this help message." + echo "" +} + +if [ $# -ne 2 ] && [ $# -ne 1 ] +then + echo "Syntax Error: not the correct number of arguments" + echo "" + usage + exit 1 +fi + +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -h|--help) + shift + usage + exit 0 + ;; + --mr-id) + MERGE_REQUEST_ID="$2" + shift + shift + ;; + *) + echo "Syntax Error: unknown option: $key" + echo "" + usage + exit 1 +esac +done + +LABELS=`curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/$MERGE_REQUEST_ID" | jq '.labels' || true` + +IS_MR_BUILD_ONLY=`echo $LABELS | grep -c BUILD-ONLY || true` +IS_MR_CI=`echo $LABELS | grep -c CI || true` +IS_MR_4G=`echo $LABELS | grep -c 4G-LTE || true` +IS_MR_5G=`echo $LABELS | grep -c 5G-NR || true` + +# First case: none is present! No CI +if [ $IS_MR_BUILD_ONLY -eq 0 ] && [ $IS_MR_CI -eq 0 ] && [ $IS_MR_4G -eq 0 ] && [ $IS_MR_5G -eq 0 ] +then + echo "NONE" + exit 0 +fi + +# Second case: Build-Only +if [ $IS_MR_BUILD_ONLY -eq 1 ] +then + echo "BUILD-ONLY" + exit 0 +fi + +# Third case: CI or 4G label --> Full CI run +if [ $IS_MR_4G -eq 1 ] || [ $IS_MR_CI -eq 1 ] +then + echo "FULL" + exit 0 +fi + +# Fourth case: 5G label +if [ $IS_MR_BUILD_ONLY -eq 0 ] && [ $IS_MR_CI -eq 0 ] && [ $IS_MR_4G -eq 0 ] && [ $IS_MR_5G -eq 1 ] +then + echo "SHORTEN-5G" + exit 0 +fi + diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py new file mode 100644 index 0000000000..0c07dfe91f --- /dev/null +++ b/ci-scripts/cls_containerize.py @@ -0,0 +1,488 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# Python for CI of OAI-eNB + COTS-UE +# +# Required Python Version +# Python 3.x +# +# Required Python Package +# pexpect +#--------------------------------------------------------------------- + +#----------------------------------------------------------- +# Import +#----------------------------------------------------------- +import sys # arg +import re # reg +import logging +import os +import time +from multiprocessing import Process, Lock, SimpleQueue +from zipfile import ZipFile + +#----------------------------------------------------------- +# OAI Testing modules +#----------------------------------------------------------- +import sshconnection as SSH +import helpreadme as HELP +import constants as CONST + +#----------------------------------------------------------- +# Class Declaration +#----------------------------------------------------------- +class Containerize(): + + def __init__(self): + + self.ranRepository = '' + self.ranBranch = '' + self.ranAllowMerge = False + self.ranCommitID = '' + self.ranTargetBranch = '' + self.eNBIPAddress = '' + self.eNBUserName = '' + self.eNBPassword = '' + self.eNBSourceCodePath = '' + self.eNB1IPAddress = '' + self.eNB1UserName = '' + self.eNB1Password = '' + self.eNB1SourceCodePath = '' + self.eNB2IPAddress = '' + self.eNB2UserName = '' + self.eNB2Password = '' + self.eNB2SourceCodePath = '' + self.forcedWorkspaceCleanup = False + self.imageKind = '' + self.eNB_instance = 0 + self.eNB_serverId = ['', '', ''] + self.yamlPath = ['', '', ''] + self.eNB_logFile = ['', '', ''] + + self.testCase_id = '' + + self.flexranCtrlDeployed = False + self.flexranCtrlIpAddress = '' + self.cli = '' + self.dockerfileprefix = '' + self.host = '' + self.allImagesSize = {} + self.collectInfo = {} +#----------------------------------------------------------- +# Container management functions +#----------------------------------------------------------- + + def BuildImage(self, HTML): + if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + if self.eNB_serverId[self.eNB_instance] == '0': + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + lSourcePath = self.eNBSourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '1': + lIpAddr = self.eNB1IPAddress + lUserName = self.eNB1UserName + lPassWord = self.eNB1Password + lSourcePath = self.eNB1SourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '2': + lIpAddr = self.eNB2IPAddress + lUserName = self.eNB2UserName + lPassWord = self.eNB2Password + lSourcePath = self.eNB2SourceCodePath + if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + logging.debug('Building on server: ' + lIpAddr) + mySSH = SSH.SSHConnection() + mySSH.open(lIpAddr, lUserName, lPassWord) + + # Checking the hostname to get adapted on cli and dockerfileprefixes + mySSH.command('hostnamectl', '\$', 5) + result = re.search('Ubuntu|Red Hat', mySSH.getBefore()) + self.host = result.group(0) + if self.host == 'Ubuntu': + self.cli = 'docker' + self.dockerfileprefix = '.ubuntu18' + elif self.host == 'Red Hat': + self.cli = 'podman' + self.dockerfileprefix = '.rhel8.2' + + imageNames = [] + result = re.search('eNB', self.imageKind) + # Creating a tupple with the imageName and the DockerFile prefix pattern on obelix + if result is not None: + imageNames.append(('oai-enb', 'eNB')) + else: + result = re.search('gNB', self.imageKind) + if result is not None: + imageNames.append(('oai-gnb', 'gNB')) + else: + result = re.search('all', self.imageKind) + if result is not None: + imageNames.append(('oai-enb', 'eNB')) + imageNames.append(('oai-gnb', 'gNB')) + imageNames.append(('oai-lte-ue', 'lteUE')) + imageNames.append(('oai-nr-ue', 'nrUE')) + if len(imageNames) == 0: + imageNames.append(('oai-enb', 'eNB')) + + # Workaround for some servers, we need to erase completely the workspace + if self.forcedWorkspaceCleanup: + mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) + + self.testCase_id = HTML.testCase_id + + # on RedHat/CentOS .git extension is mandatory + 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' + mySSH.command('mkdir -p ' + lSourcePath, '\$', 5) + mySSH.command('cd ' + lSourcePath, '\$', 5) + mySSH.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 + mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) + mySSH.command('git config user.name "OAI Jenkins"', '\$', 5) + + mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) + mySSH.command('mkdir -p cmake_targets/log', '\$', 5) + # if the commit ID is provided use it to point to it + if self.ranCommitID != '': + mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) + # if the branch is not develop, then it is a merge request and we need to do + # the potential merge. Note that merge conflicts should already been checked earlier + imageTag = 'develop' + if (self.ranAllowMerge): + imageTag = 'ci-temp' + if self.ranTargetBranch == '': + if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): + mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) + else: + logging.debug('Merging with the target branch: ' + self.ranTargetBranch) + mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) + + # if asterix, copy the entitlement and subscription manager configurations + if self.host == 'Red Hat': + mySSH.command('mkdir -p tmp/ca/', '\$', 5) + mySSH.command('mkdir -p tmp/entitlement/', '\$', 5) + mySSH.command('sudo cp /etc/rhsm/ca/redhat-uep.pem tmp/ca/', '\$', 5) + mySSH.command('sudo cp /etc/pki/entitlement/*.pem tmp/entitlement/', '\$', 5) + + #mySSH.close() + #return 0 + sharedimage = 'ran-build' + # Let's remove any previous run artifacts if still there + mySSH.command(self.cli + ' image prune --force', '\$', 5) + mySSH.command(self.cli + ' image rm ' + sharedimage + ':' + imageTag, '\$', 5) + for image,pattern in imageNames: + mySSH.command(self.cli + ' image rm ' + image + ':' + imageTag, '\$', 5) + # Build the shared image + mySSH.command(self.cli + ' build --target ' + sharedimage + ' --tag ' + sharedimage + ':' + imageTag + ' --file docker/Dockerfile.ran' + self.dockerfileprefix + ' --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > cmake_targets/log/ran-build.log 2>&1', '\$', 1600) + # Build the target image(s) + previousImage = sharedimage + ':' + imageTag + danglingShaOnes=[] + for image,pattern in imageNames: + # the archived Dockerfiles have "ran-build:latest" as base image + # we need to update them with proper tag + mySSH.command('sed -i -e "s#' + sharedimage + ':latest#' + sharedimage + ':' + imageTag + '#" docker/Dockerfile.' + pattern + self.dockerfileprefix, '\$', 5) + mySSH.command(self.cli + ' build --target ' + image + ' --tag ' + image + ':' + imageTag + ' --file docker/Dockerfile.' + pattern + self.dockerfileprefix + ' . > cmake_targets/log/' + image + '.log 2>&1', '\$', 1200) + # Retrieving the dangling image(s) for the log collection + mySSH.command(self.cli + ' images --filter "dangling=true" --filter "since=' + previousImage + '" -q | sed -e "s#^#sha=#"', '\$', 5) + result = re.search('sha=(?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) + if result is not None: + danglingShaOnes.append((image, result.group('imageShaOne'))) + previousImage = image + ':' + imageTag + + imageTag = 'ci-temp' + # First verify if images were properly created. + status = True + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + sharedimage + ':' + imageTag, '\$', 5) + if mySSH.getBefore().count('No such object') != 0: + logging.error('Could not build properly ran-build') + status = False + else: + result = re.search('Size *= *(?P[0-9\-]+) *bytes', mySSH.getBefore()) + if result is not None: + imageSize = float(result.group('size')) + imageSize = imageSize / 1000 + if imageSize < 1000: + logging.debug('\u001B[1m ran-build size is ' + ('%.0f' % imageSize) + ' kbytes\u001B[0m') + self.allImagesSize['ran-build'] = str(round(imageSize,1)) + ' kbytes' + else: + imageSize = imageSize / 1000 + if imageSize < 1000: + logging.debug('\u001B[1m ran-build size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m') + self.allImagesSize['ran-build'] = str(round(imageSize,1)) + ' Mbytes' + else: + imageSize = imageSize / 1000 + logging.debug('\u001B[1m ran-build size is ' + ('%.3f' % imageSize) + ' Gbytes\u001B[0m') + self.allImagesSize['ran-build'] = str(round(imageSize,1)) + ' Gbytes' + else: + logging.debug('ran-build size is unknown') + for image,pattern in imageNames: + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' ' + image + ':' + imageTag, '\$', 5) + if mySSH.getBefore().count('No such object') != 0: + logging.error('Could not build properly ' + image) + status = False + else: + result = re.search('Size *= *(?P[0-9\-]+) *bytes', mySSH.getBefore()) + if result is not None: + imageSize = float(result.group('size')) + imageSize = imageSize / 1000 + if imageSize < 1000: + logging.debug('\u001B[1m ' + image + ' size is ' + ('%.0f' % imageSize) + ' kbytes\u001B[0m') + self.allImagesSize[image] = str(round(imageSize,1)) + ' kbytes' + else: + imageSize = imageSize / 1000 + if imageSize < 1000: + logging.debug('\u001B[1m ' + image + ' size is ' + ('%.0f' % imageSize) + ' Mbytes\u001B[0m') + self.allImagesSize[image] = str(round(imageSize,1)) + ' Mbytes' + else: + imageSize = imageSize / 1000 + logging.debug('\u001B[1m ' + image + ' size is ' + ('%.3f' % imageSize) + ' Gbytes\u001B[0m') + self.allImagesSize[image] = str(round(imageSize,1)) + ' Gbytes' + else: + logging.debug('ran-build size is unknown') + if not status: + mySSH.close() + logging.error('\u001B[1m Building OAI Images Failed\u001B[0m') + HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK) + #HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize) + HTML.CreateHtmlTabFooter(False) + sys.exit(1) + + # Recover build logs, for the moment only possible when build is successful + mySSH.command(self.cli + ' create --name test ' + sharedimage + ':' + imageTag, '\$', 5) + mySSH.command('mkdir -p cmake_targets/log/ran-build', '\$', 5) + mySSH.command(self.cli + ' cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/ran-build', '\$', 5) + mySSH.command(self.cli + ' rm -f test', '\$', 5) + for image,shaone in danglingShaOnes: + mySSH.command('mkdir -p cmake_targets/log/' + image, '\$', 5) + mySSH.command(self.cli + ' create --name test ' + shaone, '\$', 5) + mySSH.command(self.cli + ' cp test:/oai-ran/cmake_targets/log/. cmake_targets/log/' + image, '\$', 5) + mySSH.command(self.cli + ' rm -f test', '\$', 5) + mySSH.command(self.cli + ' image prune --force', '\$', 5) + mySSH.command('cd cmake_targets', '\$', 5) + mySSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) + mySSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) + #mySSH.close() + + mySSH.command('cd /tmp/CI-eNB/cmake_targets', '\$', 5) + if (os.path.isfile('./build_log_' + self.testCase_id + '.zip')): + os.remove('./build_log_' + self.testCase_id + '.zip') + mySSH.command('zip -r -qq build_log_' + self.testCase_id + '.zip build_log_' + self.testCase_id, '\$', 5) + mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '.zip', '.') + #mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5) + mySSH.close() + ZipFile('build_log_' + self.testCase_id + '.zip').extractall('.') + + #Trying to identify the errors and warnings for each built images + imageNames1 = imageNames + shared = ('ran-build','ran') + imageNames1.insert(0, shared) + for image,pattern in imageNames1: + files = {} + file_list = [f for f in os.listdir('build_log_' + self.testCase_id + '/' + image) if os.path.isfile(os.path.join('build_log_' + self.testCase_id + '/' + image, f)) and f.endswith('.txt')] + for fil in file_list: + errorandwarnings = {} + warningsNo = 0 + errorsNo = 0 + with open('build_log_{}/{}/{}'.format(self.testCase_id,image,fil), mode='r') as inputfile: + for line in inputfile: + result = re.search(' ERROR ', str(line)) + if result is not None: + errorsNo += 1 + result = re.search(' error:', str(line)) + if result is not None: + errorsNo += 1 + result = re.search(' WARNING ', str(line)) + if result is not None: + warningsNo += 1 + result = re.search(' warning:', str(line)) + if result is not None: + warningsNo += 1 + errorandwarnings['errors'] = errorsNo + errorandwarnings['warnings'] = warningsNo + errorandwarnings['status'] = status + files[fil] = errorandwarnings + self.collectInfo[image] = files + + logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m') + HTML.CreateHtmlTestRow(self.imageKind, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize) + + def DeployObject(self, HTML, EPC): + if self.eNB_serverId[self.eNB_instance] == '0': + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + lSourcePath = self.eNBSourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '1': + lIpAddr = self.eNB1IPAddress + lUserName = self.eNB1UserName + lPassWord = self.eNB1Password + lSourcePath = self.eNB1SourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '2': + lIpAddr = self.eNB2IPAddress + lUserName = self.eNB2UserName + lPassWord = self.eNB2Password + lSourcePath = self.eNB2SourceCodePath + if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + logging.debug('\u001B[1m Deploying OAI Object on server: ' + lIpAddr + '\u001B[0m') + mySSH = SSH.SSHConnection() + mySSH.open(lIpAddr, lUserName, lPassWord) + # Putting the CPUs in a good state, we do that only on a few servers + mySSH.command('hostname', '\$', 5) + result = re.search('obelix|asterix', mySSH.getBefore()) + if result is not None: + mySSH.command('if command -v cpupower &> /dev/null; then echo ' + lPassWord + ' | sudo -S cpupower idle-set -D 0; fi', '\$', 5) + time.sleep(5) + + mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) + mySSH.command('cp docker-compose.yml ci-docker-compose.yml', '\$', 5) + imageTag = 'develop' + if (self.ranAllowMerge): + imageTag = 'ci-temp' + mySSH.command('sed -i -e "s/image: oai-enb:latest/image: oai-enb:' + imageTag + '/" ci-docker-compose.yml', '\$', 2) + localMmeIpAddr = EPC.MmeIPAddress + mySSH.command('sed -i -e "s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/" ci-docker-compose.yml', '\$', 2) + if self.flexranCtrlDeployed: + mySSH.command('sed -i -e \'s/FLEXRAN_ENABLED:.*/FLEXRAN_ENABLED: "yes"/\' ci-docker-compose.yml', '\$', 2) + mySSH.command('sed -i -e "s/CI_FLEXRAN_CTL_IP_ADDR/' + self.flexranCtrlIpAddress + '/" ci-docker-compose.yml', '\$', 2) + else: + mySSH.command('sed -i -e "s/FLEXRAN_ENABLED:.*$/FLEXRAN_ENABLED: \"no\"/" ci-docker-compose.yml', '\$', 2) + mySSH.command('sed -i -e "s/CI_FLEXRAN_CTL_IP_ADDR/127.0.0.1/" ci-docker-compose.yml', '\$', 2) + # Currently support only one + mySSH.command('docker-compose --file ci-docker-compose.yml config --services | sed -e "s@^@service=@"', '\$', 2) + result = re.search('service=(?P[a-zA-Z0-9\_]+)', mySSH.getBefore()) + if result is not None: + svcName = result.group('svc_name') + mySSH.command('docker-compose --file ci-docker-compose.yml up -d ' + svcName, '\$', 2) + + # Checking Status + mySSH.command('docker-compose --file ci-docker-compose.yml config', '\$', 5) + result = re.search('container_name: (?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) + unhealthyNb = 0 + healthyNb = 0 + startingNb = 0 + containerName = '' + if result is not None: + containerName = result.group('container_name') + time.sleep(5) + cnt = 0 + while (cnt < 3): + mySSH.command('docker inspect --format=\'{{.State.Health.Status}}\' ' + containerName, '\$', 5) + unhealthyNb = mySSH.getBefore().count('unhealthy') + healthyNb = mySSH.getBefore().count('healthy') - unhealthyNb + startingNb = mySSH.getBefore().count('starting') + if healthyNb == 1: + cnt = 10 + else: + time.sleep(10) + cnt += 1 + logging.debug(' -- ' + str(healthyNb) + ' healthy container(s)') + logging.debug(' -- ' + str(unhealthyNb) + ' unhealthy container(s)') + logging.debug(' -- ' + str(startingNb) + ' still starting container(s)') + + status = False + if healthyNb == 1: + cnt = 0 + while (cnt < 20): + mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting"', '\$', 30) + result = re.search('got sync|Starting F1AP at CU', mySSH.getBefore()) + if result is None: + time.sleep(6) + cnt += 1 + else: + cnt = 100 + status = True + logging.info('\u001B[1m Deploying OAI object Pass\u001B[0m') + time.sleep(10) + mySSH.close() + + self.testCase_id = HTML.testCase_id + self.eNB_logFile[self.eNB_instance] = 'enb_' + self.testCase_id + '.log' + + if status: + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + else: + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) + + def UndeployObject(self, HTML, RAN): + logging.info('\u001B[1m Undeploying OAI Object Pass\u001B[0m') + if self.eNB_serverId[self.eNB_instance] == '0': + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + lSourcePath = self.eNBSourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '1': + lIpAddr = self.eNB1IPAddress + lUserName = self.eNB1UserName + lPassWord = self.eNB1Password + lSourcePath = self.eNB1SourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '2': + lIpAddr = self.eNB2IPAddress + lUserName = self.eNB2UserName + lPassWord = self.eNB2Password + lSourcePath = self.eNB2SourceCodePath + if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + logging.debug('\u001B[1m Deploying OAI Object on server: ' + lIpAddr + '\u001B[0m') + mySSH = SSH.SSHConnection() + mySSH.open(lIpAddr, lUserName, lPassWord) + mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) + # Currently support only one + mySSH.command('docker-compose --file ci-docker-compose.yml config', '\$', 5) + result = re.search('container_name: (?P[a-zA-Z0-9\-\_]+)', mySSH.getBefore()) + if result is not None: + containerName = result.group('container_name') + mySSH.command('docker kill --signal INT ' + containerName, '\$', 30) + time.sleep(5) + mySSH.command('docker logs ' + containerName + ' > ' + lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '\$', 30) + mySSH.command('docker rm -f ' + containerName, '\$', 30) + + # Putting the CPUs back in a idle state, we do that only on a few servers + mySSH.command('hostname', '\$', 5) + result = re.search('obelix|asterix', mySSH.getBefore()) + if result is not None: + mySSH.command('if command -v cpupower &> /dev/null; then echo ' + lPassWord + ' | sudo -S cpupower idle-set -E; fi', '\$', 5) + mySSH.close() + + # Analyzing log file! + copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + self.eNB_logFile[self.eNB_instance], '.') + nodeB_prefix = 'e' + if (copyin_res == -1): + HTML.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) + else: + logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + self.eNB_logFile[self.eNB_instance]) + logStatus = RAN.AnalyzeLogFile_eNB(self.eNB_logFile[self.eNB_instance], HTML) + if (logStatus < 0): + HTML.CreateHtmlTestRow(RAN.runtime_stats, 'KO', logStatus) + else: + HTML.CreateHtmlTestRow(RAN.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py new file mode 100644 index 0000000000..7da829b7f7 --- /dev/null +++ b/ci-scripts/cls_oaicitest.py @@ -0,0 +1,3312 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# +# Required Python Version +# Python 3.x +# +# Required Python Package +# pexpect +#--------------------------------------------------------------------- + + +#----------------------------------------------------------- +# Import Libs +#----------------------------------------------------------- +import sys # arg +import re # reg +import pexpect # pexpect +import time # sleep +import os +import subprocess +import xml.etree.ElementTree as ET +import logging +import datetime +import signal +import statistics as stat +from multiprocessing import Process, Lock, SimpleQueue +logging.basicConfig( + level=logging.DEBUG, + format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" +) + +#import our libs +import helpreadme as HELP +import constants as CONST +import sshconnection + + + + +#----------------------------------------------------------- +# Utility functions +#----------------------------------------------------------- + +def GetPingTimeAnalysis(ping_log_file): + #ping time values read from file + t_ping=[] + #ping stats (dictionary) to be returned by the function + ping_stat={} + if (os.path.isfile(ping_log_file)): + with open(ping_log_file,"r") as f: + for line in f: + #looking for time=xxx ms field + result=re.match('^.+time=(?P[0-9\.]+)',line) + if result != None: + t_ping.append(float(result.group('ping_time'))) + + #initial stats + ping_stat['min_0']=min(t_ping) + ping_stat['mean_0']=stat.mean(t_ping) + ping_stat['median_0']=stat.median(t_ping) + ping_stat['max_0']=max(t_ping) + + #get index of max value + + max_loc=t_ping.index(max(t_ping)) + ping_stat['max_loc']=max_loc + #remove it + t_ping.pop(max_loc) + #new stats after removing max value + ping_stat['min_1']=min(t_ping) + ping_stat['mean_1']=stat.mean(t_ping) + ping_stat['median_1']=stat.median(t_ping) + ping_stat['max_1']=max(t_ping) + + return ping_stat + + else: + logging.error("Ping log file does not exist") + return -1 + + + +#----------------------------------------------------------- +# OaiCiTest Class Definition +#----------------------------------------------------------- +class OaiCiTest(): + + def __init__(self): + self.ranRepository = '' + self.ranBranch = '' + self.ranCommitID = '' + self.ranAllowMerge = False + self.ranTargetBranch = '' + + self.FailReportCnt = 0 + self.ADBIPAddress = '' + self.ADBUserName = '' + self.ADBPassword = '' + self.ADBCentralized = True + self.testCase_id = '' + self.testXMLfiles = [] + self.testUnstable = False + self.testMinStableId = '999999' + self.testStabilityPointReached = False + self.desc = '' + self.ping_args = '' + self.ping_packetloss_threshold = '' + self.iperf_args = '' + self.iperf_packetloss_threshold = '' + self.iperf_profile = '' + self.iperf_options = '' + self.nbMaxUEtoAttach = -1 + self.UEDevices = [] + self.UEDevicesStatus = [] + self.UEDevicesRemoteServer = [] + self.UEDevicesRemoteUser = [] + self.UEDevicesOffCmd = [] + self.UEDevicesOnCmd = [] + self.UEDevicesRebootCmd = [] + self.CatMDevices = [] + self.UEIPAddresses = [] + self.idle_sleep_time = 0 + self.x2_ho_options = 'network' + self.x2NbENBs = 0 + self.x2ENBBsIds = [] + self.x2ENBConnectedUEs = [] + self.repeatCounts = [] + self.finalStatus = False + self.UEIPAddress = '' + self.UEUserName = '' + self.UEPassword = '' + self.UE_instance = 0 + self.UESourceCodePath = '' + self.UELogFile = '' + self.Build_OAI_UE_args = '' + self.Initialize_OAI_UE_args = '' + self.clean_repository = True + self.air_interface='' + self.expectedNbOfConnectedUEs = 0 + + + def BuildOAIUE(self,HTML): + if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + result = re.search('--nrUE', self.Build_OAI_UE_args) + if result is not None: + self.air_interface='nr-uesoftmodem' + ue_prefix = 'NR ' + else: + self.air_interface='lte-uesoftmodem' + ue_prefix = '' + 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' + SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) + SSH.command('cd ' + self.UESourceCodePath, '\$', 5) + SSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) + # here add a check if git clone or git fetch went smoothly + SSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) + SSH.command('git config user.name "OAI Jenkins"', '\$', 5) + if self.clean_repository: + SSH.command('ls *.txt', '\$', 5) + result = re.search('LAST_BUILD_INFO', SSH.getBefore()) + if result is not None: + mismatch = False + SSH.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) + result = re.search(self.ranCommitID, SSH.getBefore()) + if result is None: + mismatch = True + SSH.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) + if self.ranAllowMerge: + result = re.search('YES', SSH.getBefore()) + if result is None: + mismatch = True + SSH.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) + if self.ranTargetBranch == '': + result = re.search('develop', SSH.getBefore()) + else: + result = re.search(self.ranTargetBranch, SSH.getBefore()) + if result is None: + mismatch = True + else: + result = re.search('NO', SSH.getBefore()) + if result is None: + mismatch = True + if not mismatch: + SSH.close() + HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK) + return + + SSH.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 != '': + SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) + # if the branch is not develop, then it is a merge request and we need to do + # the potential merge. Note that merge conflicts should already been checked earlier + if self.ranAllowMerge: + if self.ranTargetBranch == '': + if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): + SSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) + else: + logging.debug('Merging with the target branch: ' + self.ranTargetBranch) + SSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) + SSH.command('source oaienv', '\$', 5) + SSH.command('cd cmake_targets', '\$', 5) + SSH.command('mkdir -p log', '\$', 5) + SSH.command('chmod 777 log', '\$', 5) + # no need to remove in log (git clean did the trick) + SSH.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 1200) + SSH.command('ls ran_build/build', '\$', 3) + SSH.command('ls ran_build/build', '\$', 3) + buildStatus = True + result = re.search(self.air_interface, SSH.getBefore()) + if result is None: + buildStatus = False + SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) + SSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) + SSH.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) + if buildStatus: + # Generating a BUILD INFO file + SSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) + SSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if self.ranAllowMerge: + SSH.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) + if self.ranTargetBranch == '': + SSH.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) + else: + SSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) + else: + SSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) + SSH.close() + HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') + else: + SSH.close() + logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') + HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', CONST.ALL_PROCESSES_OK, 'OAI UE') + HTML.CreateHtmlTabFooter(False) + self.ConditionalExit() + + def CheckFlexranCtrlInstallation(self,RAN,EPC,CONTAINERS): + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': + return + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) + result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore()) + if result is not None: + RAN.flexranCtrlInstalled=True + RAN.flexranCtrlIpAddress=EPC.IPAddress + logging.debug('Flexran Controller is installed') + else: + # Maybe flexran-rtc is deployed into a container + SSH.command('docker inspect --format="FLEX_RTC_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" prod-flexran-rtc', '\$', 5) + result = re.search('FLEX_RTC_IP_ADDR = (?P[0-9\.]+)', SSH.getBefore()) + if result is not None: + RAN.flexranCtrlDeployed=True + RAN.flexranCtrlIpAddress=result.group('flex_ip_addr') + CONTAINERS.flexranCtrlDeployed=True + CONTAINERS.flexranCtrlIpAddress=result.group('flex_ip_addr') + logging.debug('Flexran Controller is deployed: ' + RAN.flexranCtrlIpAddress) + SSH.close() + + def InitializeFlexranCtrl(self, HTML,RAN,EPC): + if RAN.flexranCtrlInstalled == False: + return + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd /opt/flexran_rtc', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S rm -f log/*.log', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) + SSH.command('ps -aux | grep --color=never rt_controller', '\$', 5) + result = re.search('rt_controller -c ', SSH.getBefore()) + if result is not None: + logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') + RAN.flexranCtrlStarted=True + SSH.close() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def InitializeUE_common(self, device_id, idx,COTS_UE): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if not self.ADBCentralized: + # Reboot UE + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) + # Wait + #time.sleep(60) + # Put in LTE-Mode only + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60) + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60) + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60) + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60) + # enable data service + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) + # we need to do radio on/off cycle to make sure of above changes + # airplane mode off // radio on + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) + #time.sleep(10) + # airplane mode on // radio off + #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) + + # normal procedure without reboot + # enable data service + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) + # airplane mode on // radio off + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) + SSH.close() + return + + #RH quick add-on to integrate cots control defined by yaml + #if device_id exists in yaml dictionary, we execute the new procedure defined in cots_ue class + #otherwise we use the legacy procedure + logging.debug('Device id ' + str(device_id) + ', in COTS UE dict : ' + str(COTS_UE.Check_Exists(device_id))) + if COTS_UE.Check_Exists(device_id): + #switch device to Airplane mode ON (ie Radio OFF) + COTS_UE.Set_Airplane(device_id, 'ON') + else: + # enable data service + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) + + # The following commands are deprecated since we no longer work on Android 7+ + # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10) + # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60) + # a dedicated script has to be installed inside the UE + # airplane mode on means call /data/local/tmp/off + if device_id == '84B7N16418004022': + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + #airplane mode off means call /data/local/tmp/on + logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m') + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def InitializeUE(self,HTML,COTS_UE): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + multi_jobs = [] + i = 0 + for device_id in self.UEDevices: + p = Process(target = self.InitializeUE_common, args = (device_id,i,COTS_UE,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i += 1 + for job in multi_jobs: + job.join() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + + + + def InitializeOAIUE(self,HTML,RAN,EPC,COTS_UE): + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + if self.air_interface == 'lte-uesoftmodem': + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is None: + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) + self.ConditionalExit() + UE_prefix = '' + else: + UE_prefix = 'NR ' + SSH = sshconnection.SSHConnection() + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + # b2xx_fx3_utils reset procedure + SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) + result = re.search('type: b200', SSH.getBefore()) + if result is not None: + logging.debug('Found a B2xx device --> resetting it') + SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) + # Reloading FGPA bin firmware + SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) + result = re.search('type: n3xx', str(SSH.getBefore())) + if result is not None: + logging.debug('Found a N3xx device --> resetting it') + SSH.command('cd ' + self.UESourceCodePath, '\$', 5) + # Initialize_OAI_UE_args usually start with -C and followed by the location in repository + SSH.command('source oaienv', '\$', 5) + SSH.command('cd cmake_targets/ran_build/build', '\$', 5) + if self.air_interface == 'lte-uesoftmodem': + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + # We may have to regenerate the .u* files + if result is None: + SSH.command('ls /tmp/*.sed', '\$', 5) + result = re.search('adapt_usim_parameters', SSH.getBefore()) + if result is not None: + SSH.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) + else: + SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) + SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) + SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) + else: + SSH.command('if [ -e rbconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm rbconfig.raw; fi', '\$', 5) + SSH.command('if [ -e reconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm reconfig.raw; fi', '\$', 5) + # Copy the RAW files from gNB running directory (maybe on another machine) + copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/rbconfig.raw', '.') + if (copyin_res == 0): + SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './rbconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build') + copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/reconfig.raw', '.') + if (copyin_res == 0): + SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build') + SSH.command('echo "ulimit -c unlimited && ./'+ self.air_interface +' ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) + self.UELogFile = 'ue_' + self.testCase_id + '.log' + + # We are now looping several times to hope we really sync w/ an eNB + doOutterLoop = True + outterLoopCounter = 5 + gotSyncStatus = True + fullSyncStatus = True + while (doOutterLoop): + SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5) + SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) + SSH.command('echo $USER; nohup sudo -E ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5) + time.sleep(6) + SSH.command('cd ../..', '\$', 5) + doLoop = True + loopCounter = 10 + gotSyncStatus = True + # the 'got sync' message is for the UE threads synchronization + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + # Here should never occur + logging.error('"got sync" message never showed!') + gotSyncStatus = False + doLoop = False + continue + SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + if self.air_interface == 'nr-uesoftmodem': + result = re.search('Starting sync detection', SSH.getBefore()) + else: + result = re.search('got sync', SSH.getBefore()) + if result is None: + time.sleep(10) + else: + doLoop = False + logging.debug('Found "got sync" message!') + if gotSyncStatus == False: + # we certainly need to stop the lte-uesoftmodem process if it is still running! + SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('-uesoftmodem', SSH.getBefore()) + if result is not None: + SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4) + time.sleep(3) + outterLoopCounter = outterLoopCounter - 1 + if (outterLoopCounter == 0): + doOutterLoop = False + continue + # We are now checking if sync w/ eNB DOES NOT OCCUR + # Usually during the cell synchronization stage, the UE returns with No cell synchronization message + # That is the case for LTE + # In NR case, it's a positive message that will show if synchronization occurs + doLoop = True + if self.air_interface == 'nr-uesoftmodem': + loopCounter = 10 + else: + # We are now checking if sync w/ eNB DOES NOT OCCUR + # Usually during the cell synchronization stage, the UE returns with No cell synchronization message + loopCounter = 10 + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + if self.air_interface == 'nr-uesoftmodem': + # Here we do have great chances that UE did NOT cell-sync w/ gNB + doLoop = False + fullSyncStatus = False + logging.debug('Never seen the NR-Sync message (Measured Carrier Frequency) --> try again') + time.sleep(6) + # Stopping the NR-UE + SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('nr-uesoftmodem', SSH.getBefore()) + if result is not None: + SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT nr-uesoftmodem', '\$', 4) + time.sleep(6) + else: + # Here we do have a great chance that the UE did cell-sync w/ eNB + doLoop = False + doOutterLoop = False + fullSyncStatus = True + continue + SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Frequency"', '\$', 4) + if self.air_interface == 'nr-uesoftmodem': + # Positive messaging --> + result = re.search('Measured Carrier Frequency', SSH.getBefore()) + if result is not None: + doLoop = False + doOutterLoop = False + fullSyncStatus = True + else: + time.sleep(6) + else: + # Negative messaging --> + result = re.search('No cell synchronization found', SSH.getBefore()) + if result is None: + time.sleep(6) + else: + doLoop = False + fullSyncStatus = False + logging.debug('Found: "No cell synchronization" message! --> try again') + time.sleep(6) + SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('lte-uesoftmodem', SSH.getBefore()) + if result is not None: + SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) + outterLoopCounter = outterLoopCounter - 1 + if (outterLoopCounter == 0): + doOutterLoop = False + + if fullSyncStatus and gotSyncStatus: + doInterfaceCheck = False + if self.air_interface == 'lte-uesoftmodem': + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is None: + doInterfaceCheck = True + # For the moment, only in explicit noS1 without kernel module (ie w/ tunnel interface) + if self.air_interface == 'nr-uesoftmodem': + result = re.search('--noS1 --nokrnmod 1', str(self.Initialize_OAI_UE_args)) + if result is not None: + doInterfaceCheck = True + if doInterfaceCheck: + SSH.command('ifconfig oaitun_ue1', '\$', 4) + SSH.command('ifconfig oaitun_ue1', '\$', 4) + # ifconfig output is different between ubuntu 16 and ubuntu 18 + result = re.search('inet addr:1|inet 1', SSH.getBefore()) + if result is not None: + logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') + tunnelInterfaceStatus = True + else: + logging.debug(SSH.getBefore()) + logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') + tunnelInterfaceStatus = False + if RAN.eNBmbmsEnables[0]: + SSH.command('ifconfig oaitun_uem1', '\$', 4) + result = re.search('inet addr', SSH.getBefore()) + if result is not None: + logging.debug('\u001B[1m oaitun_uem1 interface is mounted and configured\u001B[0m') + tunnelInterfaceStatus = tunnelInterfaceStatus and True + else: + logging.error('\u001B[1m oaitun_uem1 interface is either NOT mounted or NOT configured\u001B[0m') + tunnelInterfaceStatus = False + else: + tunnelInterfaceStatus = True + else: + tunnelInterfaceStatus = True + + SSH.close() + if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') + logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') + if (self.ADBIPAddress != 'none'): + self.UEDevices = [] + self.UEDevices.append('OAI-UE') + self.UEDevicesStatus = [] + self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) + else: + if self.air_interface == 'lte-uesoftmodem': + if RAN.eNBmbmsEnables[0]: + HTML.htmlUEFailureMsg='oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' + else: + HTML.htmlUEFailureMsg='oaitun_ue1 interface is either NOT mounted or NOT configured' + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') + else: + HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced' + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') + logging.error('\033[91mInitialize OAI UE Failed! \033[0m') + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def checkDevTTYisUnlocked(self): + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + count = 0 + while count < 5: + SSH.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10) + result = re.search('picocom', SSH.getBefore()) + if result is None: + count = 10 + else: + time.sleep(5) + count = count + 1 + SSH.close() + + def InitializeCatM(self,HTML): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.enablePicocomClosure() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` + SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) + SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) + time.sleep(1) + # Calling twice AT to clear all buffers + SSH.command('AT', 'OK|ERROR', 5) + SSH.command('AT', 'OK', 5) + # Doing a power cycle + SSH.command('AT^RESET', 'SIMSTORE,READY', 15) + SSH.command('AT', 'OK|ERROR', 5) + SSH.command('AT', 'OK', 5) + SSH.command('ATE1', 'OK', 5) + # Disabling the Radio + SSH.command('AT+CFUN=0', 'OK', 5) + logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') + # Checking if auto-attach is enabled + SSH.command('AT^AUTOATT?', 'OK', 5) + result = re.search('AUTOATT: (?P[0-9\-]+)', SSH.getBefore()) + if result is not None: + if result.group('state') is not None: + autoAttachState = int(result.group('state')) + if autoAttachState is not None: + if autoAttachState == 0: + SSH.command('AT^AUTOATT=1', 'OK', 5) + logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m') + else: + logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m') + # Force closure of picocom but device might still be locked + SSH.close() + SSH.disablePicocomClosure() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + self.checkDevTTYisUnlocked() + + def TerminateCatM(self,HTML): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.enablePicocomClosure() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` + SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) + SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) + time.sleep(1) + # Calling twice AT to clear all buffers + SSH.command('AT', 'OK|ERROR', 5) + SSH.command('AT', 'OK', 5) + # Disabling the Radio + SSH.command('AT+CFUN=0', 'OK', 5) + logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') + SSH.close() + SSH.disablePicocomClosure() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + self.checkDevTTYisUnlocked() + + def AttachCatM(self,HTML,RAN,COTS_UE,EPC): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.enablePicocomClosure() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` + SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) + SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) + time.sleep(1) + # Calling twice AT to clear all buffers + SSH.command('AT', 'OK|ERROR', 5) + SSH.command('AT', 'OK', 5) + # Enabling the Radio + SSH.command('AT+CFUN=1', 'SIMSTORE,READY', 5) + logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m') + time.sleep(4) + # We should check if we register + count = 0 + attach_cnt = 0 + attach_status = False + while count < 5: + SSH.command('AT+CEREG?', 'OK', 5) + result = re.search('CEREG: 2,(?P[0-9\-]+),', SSH.getBefore()) + if result is not None: + mDataConnectionState = int(result.group('state')) + if mDataConnectionState is not None: + if mDataConnectionState == 1: + count = 10 + attach_status = True + result = re.search('CEREG: 2,1,"(?P[0-9A-Z]+)","(?P[0-9A-Z]+)"', SSH.getBefore()) + if result is not None: + networky = result.group('networky') + networkz = result.group('networkz') + logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m') + else: + logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m') + else: + logging.debug('+CEREG: 2,' + str(mDataConnectionState)) + attach_cnt = attach_cnt + 1 + else: + logging.debug(SSH.getBefore()) + attach_cnt = attach_cnt + 1 + count = count + 1 + time.sleep(1) + if attach_status: + SSH.command('AT+CESQ', 'OK', 5) + result = re.search('CESQ: 99,99,255,255,(?P[0-9]+),(?P[0-9]+)', SSH.getBefore()) + if result is not None: + nRSRQ = int(result.group('rsrq')) + nRSRP = int(result.group('rsrp')) + if (nRSRQ is not None) and (nRSRP is not None): + logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB') + logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm') + SSH.close() + SSH.disablePicocomClosure() + html_queue = SimpleQueue() + self.checkDevTTYisUnlocked() + if attach_status: + 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
' + else: + html_cell += '' + html_queue.put(html_cell) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) + else: + logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') + html_cell = '
CAT-M module Attachment Failed
' + html_queue.put(html_cell) + HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def PingCatM(self,HTML,RAN,EPC,COTS_UE): + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + try: + statusQueue = SimpleQueue() + lock = Lock() + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) + SSH.command('cd scripts', '\$', 5) + if re.match('OAI', EPC.Type, re.IGNORECASE): + logging.debug('Using the OAI EPC HSS: not implemented yet') + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) + self.ConditionalExit() + else: + SSH.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) + result = re.search('Allocated ipv4 addr: (?P[0-9\.]+) from Pool', SSH.getBefore()) + if result is not None: + moduleIPAddr = result.group('ipaddr') + else: + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + ping_time = re.findall("-c (\d+)",str(self.ping_args)) + device_id = 'catm' + ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + result = re.search(', (?P[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) + if result is None: + message = 'Packet Loss Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + packetloss = result.group('packetloss') + if float(packetloss) == 100: + message = 'Packet Loss is 100%' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + result = re.search('rtt min\/avg\/max\/mdev = (?P[0-9\.]+)\/(?P[0-9\.]+)\/(?P[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) + if result is None: + message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) + return + rtt_min = result.group('rtt_min') + rtt_avg = result.group('rtt_avg') + rtt_max = result.group('rtt_max') + pal_msg = 'Packet Loss : ' + packetloss + '%' + min_msg = 'RTT(Min) : ' + rtt_min + ' ms' + avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' + max_msg = 'RTT(Max) : ' + rtt_max + ' ms' + lock.acquire() + logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m') + logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') + qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg + packetLossOK = True + if packetloss is not None: + if float(packetloss) > float(self.ping_packetloss_threshold): + qMsg += '\nPacket Loss too high' + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + packetLossOK = False + elif float(packetloss) > 0: + qMsg += '\nPacket Loss is not 0%' + logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') + lock.release() + SSH.close() + html_cell = '
CAT-M module\nIP Address  : ' + moduleIPAddr + '\n' + qMsg + '
' + statusQueue.put(html_cell) + if (packetLossOK): + HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) + else: + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def AttachUE_common(self, device_id, statusQueue, lock, idx,COTS_UE): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if self.ADBCentralized: + #RH quick add on to integrate cots control defined by yaml + #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class + #otherwise we use the legacy procedure + if COTS_UE.Check_Exists(device_id): + #switch device to Airplane mode OFF (ie Radio ON) + COTS_UE.Set_Airplane(device_id, 'OFF') + elif device_id == '84B7N16418004022': + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + else: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + else: + # airplane mode off // radio on + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) + time.sleep(2) + max_count = 45 + count = max_count + while count > 0: + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) + result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', SSH.getBefore()) + if result is None: + logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put('mDataConnectionState Not Found!') + lock.release() + break + mDataConnectionState = int(result.group('state')) + if mDataConnectionState == 2: + logging.debug('\u001B[1mUE (' + device_id + ') Attach Completed\u001B[0m') + lock.acquire() + statusQueue.put(max_count - count) + statusQueue.put(device_id) + statusQueue.put('Attach Completed') + lock.release() + break + count = count - 1 + if count == 15 or count == 30: + logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') + if self.ADBCentralized: + #RH quick add on to intgrate cots control defined by yaml + #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class + #otherwise we use the legacy procedure + if COTS_UE.Check_Exists(device_id): + #switch device to Airplane mode ON (ie Radio OFF) + COTS_UE.Set_Airplane(device_id, 'ON') + elif device_id == '84B7N16418004022': + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) + time.sleep(0.5) + if self.ADBCentralized: + #RH quick add on to integrate cots control defined by yaml + #if device id exists in yaml dictionary, we execute the new procedre defined incots_ue class + #otherwise we use the legacy procedure + if COTS_UE.Check_Exists(device_id): + #switch device to Airplane mode OFF (ie Radio ON) + COTS_UE.Set_Airplane(device_id, 'OFF') + elif device_id == '84B7N16418004022': + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) + else: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) + time.sleep(0.5) + logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') + time.sleep(1) + if count == 0: + logging.debug('\u001B[1;37;41m UE (' + device_id + ') Attach Failed \u001B[0m') + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put('Attach Failed') + lock.release() + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def AttachUE(self,HTML,RAN,EPC,COTS_UE): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + multi_jobs = [] + status_queue = SimpleQueue() + lock = Lock() + nb_ue_to_connect = 0 + for device_id in self.UEDevices: + if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): + self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING + p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,COTS_UE,)) + p.daemon = True + p.start() + multi_jobs.append(p) + nb_ue_to_connect = nb_ue_to_connect + 1 + for job in multi_jobs: + job.join() + + if (status_queue.empty()): + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + else: + attach_status = True + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + attach_status = False + device_id = status_queue.get() + message = status_queue.get() + if (count < 0): + html_cell = '
UE (' + device_id + ')\n' + message + '
' + else: + html_cell = '
UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds
' + html_queue.put(html_cell) + if (attach_status): + cnt = 0 + while cnt < len(self.UEDevices): + if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING: + self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED + cnt += 1 + HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) + if result is not None: + logging.debug('Waiting 5 seconds to fill up record file') + time.sleep(5) + else: + HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def DetachUE_common(self, device_id, idx,COTS_UE): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if self.ADBCentralized: + #RH quick add on to integrate cots control defined by yaml + #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class + #otherwise we use the legacy procedure + if COTS_UE.Check_Exists(device_id): + #switch device to Airplane mode ON (ie Radio OFF) + COTS_UE.Set_Airplane(device_id,'ON') + elif device_id == '84B7N16418004022': + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) + logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def DetachUE(self,HTML,RAN,EPC,COTS_UE): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + multi_jobs = [] + cnt = 0 + for device_id in self.UEDevices: + self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING + p = Process(target = self.DetachUE_common, args = (device_id,cnt,COTS_UE,)) + p.daemon = True + p.start() + multi_jobs.append(p) + cnt += 1 + for job in multi_jobs: + job.join() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) + if result is not None: + logging.debug('Waiting 5 seconds to fill up record file') + time.sleep(5) + cnt = 0 + while cnt < len(self.UEDevices): + self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED + cnt += 1 + + def RebootUE_common(self, device_id): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + previousmDataConnectionStates = [] + # Save mDataConnectionState + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) + result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', SSH.getBefore()) + if result is None: + logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') + sys.exit(1) + previousmDataConnectionStates.append(int(result.group('state'))) + # Reboot UE + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10) + time.sleep(60) + previousmDataConnectionState = previousmDataConnectionStates.pop(0) + count = 180 + while count > 0: + count = count - 1 + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) + result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', SSH.getBefore()) + if result is None: + mDataConnectionState = None + else: + mDataConnectionState = int(result.group('state')) + logging.debug('mDataConnectionState = ' + result.group('state')) + if mDataConnectionState is None or (previousmDataConnectionState == 2 and mDataConnectionState != 2): + logging.debug('\u001B[1mWait UE (' + device_id + ') a second until reboot completion (' + str(180-count) + ' times)\u001B[0m') + time.sleep(1) + else: + logging.debug('\u001B[1mUE (' + device_id + ') Reboot Completed\u001B[0m') + break + if count == 0: + logging.debug('\u001B[1;37;41m UE (' + device_id + ') Reboot Failed \u001B[0m') + sys.exit(1) + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def RebootUE(self,HTML,RAN,EPC): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) + self.ConditionalExit() + multi_jobs = [] + for device_id in self.UEDevices: + p = Process(target = self.RebootUE_common, args = (device_id,)) + p.daemon = True + p.start() + multi_jobs.append(p) + for job in multi_jobs: + job.join() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def DataDisableUE_common(self, device_id, idx): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # disable data service + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60) + logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m') + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def DataDisableUE(self,HTML): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + multi_jobs = [] + i = 0 + for device_id in self.UEDevices: + p = Process(target = self.DataDisableUE_common, args = (device_id,i,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i += 1 + for job in multi_jobs: + job.join() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def DataEnableUE_common(self, device_id, idx): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # enable data service + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) + logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m') + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def DataEnableUE(self,HTML): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + multi_jobs = [] + i = 0 + for device_id in self.UEDevices: + p = Process(target = self.DataEnableUE_common, args = (device_id,i,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i += 1 + for job in multi_jobs: + job.join() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def GetAllUEDevices(self, terminate_ue_flag): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if self.ADBCentralized: + SSH.command('adb devices', '\$', 15) + self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) + #report number and id of devices found + msg = "UEDevices found by GetAllUEDevices : " + " ".join(self.UEDevices) + logging.debug(msg) + SSH.close() + else: + if (os.path.isfile('./phones_list.txt')): + os.remove('./phones_list.txt') + SSH.command('ls /etc/*/phones*.txt', '\$', 5) + result = re.search('/etc/ci/phones_list.txt', SSH.getBefore()) + SSH.close() + if (result is not None) and (len(self.UEDevices) == 0): + SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.') + if (os.path.isfile('./phones_list.txt')): + phone_list_file = open('./phones_list.txt', 'r') + for line in phone_list_file.readlines(): + line = line.strip() + result = re.search('^#', line) + if result is not None: + continue + comma_split = line.split(",") + self.UEDevices.append(comma_split[0]) + self.UEDevicesRemoteServer.append(comma_split[1]) + self.UEDevicesRemoteUser.append(comma_split[2]) + self.UEDevicesOffCmd.append(comma_split[3]) + self.UEDevicesOnCmd.append(comma_split[4]) + self.UEDevicesRebootCmd.append(comma_split[5]) + phone_list_file.close() + + # better handling of the case when no UE detected + # Sys-exit is now dealt by the calling function + if terminate_ue_flag == True: + if len(self.UEDevices) == 0: + logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') + return False + if len(self.UEDevicesStatus) == 0: + cnt = 0 + while cnt < len(self.UEDevices): + self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) + cnt += 1 + return True + + def GetAllCatMDevices(self, terminate_ue_flag): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if self.ADBCentralized: + SSH.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) + #self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) + self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) + else: + if (os.path.isfile('./modules_list.txt')): + os.remove('./modules_list.txt') + SSH.command('ls /etc/*/modules*.txt', '\$', 5) + result = re.search('/etc/ci/modules_list.txt', SSH.getBefore()) + SSH.close() + if result is not None: + logging.debug('Found a module list file on ADB server') + if terminate_ue_flag == True: + if len(self.CatMDevices) == 0: + logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') + sys.exit(1) + SSH.close() + + def CheckUEStatus_common(self, lock, device_id, statusQueue, idx): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60) + result = re.search('mServiceState=(?P[0-9]+)', SSH.getBefore()) + serviceState = 'Service State: UNKNOWN' + if result is not None: + lServiceState = int(result.group('serviceState')) + if lServiceState == 3: + serviceState = 'Service State: RADIO_POWERED_OFF' + if lServiceState == 1: + serviceState = 'Service State: OUT_OF_SERVICE' + if lServiceState == 0: + serviceState = 'Service State: IN_SERVICE' + if lServiceState == 2: + serviceState = 'Service State: EMERGENCY_ONLY' + result = re.search('mDataConnectionState=(?P[0-9]+)', SSH.getBefore()) + dataConnectionState = 'Data State: UNKNOWN' + if result is not None: + lDataConnectionState = int(result.group('dataConnectionState')) + if lDataConnectionState == 0: + dataConnectionState = 'Data State: DISCONNECTED' + if lDataConnectionState == 1: + dataConnectionState = 'Data State: CONNECTING' + if lDataConnectionState == 2: + dataConnectionState = 'Data State: CONNECTED' + if lDataConnectionState == 3: + dataConnectionState = 'Data State: SUSPENDED' + result = re.search('mDataConnectionReason=(?P[0-9a-zA-Z_]+)', SSH.getBefore()) + time.sleep(1) + SSH.close() + dataConnectionReason = 'Data Reason: UNKNOWN' + if result is not None: + dataConnectionReason = 'Data Reason: ' + result.group('dataConnectionReason') + lock.acquire() + logging.debug('\u001B[1;37;44m Status Check (' + str(device_id) + ') \u001B[0m') + logging.debug('\u001B[1;34m ' + serviceState + '\u001B[0m') + logging.debug('\u001B[1;34m ' + dataConnectionState + '\u001B[0m') + logging.debug('\u001B[1;34m ' + dataConnectionReason + '\u001B[0m') + statusQueue.put(0) + statusQueue.put(device_id) + qMsg = serviceState + '\n' + dataConnectionState + '\n' + dataConnectionReason + statusQueue.put(qMsg) + lock.release() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def CheckStatusUE(self,HTML,RAN,EPC,COTS_UE): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) + HTML.CreateHtmlTabFooter(False) + self.ConditionalExit() + multi_jobs = [] + lock = Lock() + status_queue = SimpleQueue() + i = 0 + for device_id in self.UEDevices: + p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,i,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i += 1 + for job in multi_jobs: + job.join() + if (RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted) or RAN.flexranCtrlDeployed: + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) + SSH.command('curl http://' + RAN.flexranCtrlIpAddress + ':9999/stats | jq \'.\' > check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) + SSH.command('cat check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5) + result = re.search('Nb Connected UE = (?P[0-9]+)', SSH.getBefore()) + passStatus = True + if result is not None: + nb_ues = int(result.group('nb_ues')) + htmlOptions = 'Nb Connected UE(s) to eNB = ' + str(nb_ues) + logging.debug('\u001B[1;37;44m ' + htmlOptions + ' \u001B[0m') + if self.expectedNbOfConnectedUEs > -1: + if nb_ues != self.expectedNbOfConnectedUEs: + passStatus = False + else: + htmlOptions = 'N/A' + SSH.close() + else: + passStatus = True + htmlOptions = 'N/A' + + if (status_queue.empty()): + HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + else: + check_status = True + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + check_status = False + device_id = status_queue.get() + message = status_queue.get() + html_cell = '
UE (' + device_id + ')\n' + message + '
' + html_queue.put(html_cell) + if check_status and passStatus: + HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) + else: + HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def GetAllUEIPAddresses(self): + SSH = sshconnection.SSHConnection() + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + ue_ip_status = 0 + self.UEIPAddresses = [] + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('ifconfig oaitun_ue1', '\$', 4) + result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', SSH.getBefore()) + if result is not None: + if result.group('ueipaddress') is not None: + UE_IPAddress = result.group('ueipaddress') + else: + UE_IPAddress = result.group('ueipaddress2') + logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') + self.UEIPAddresses.append(UE_IPAddress) + else: + logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') + ue_ip_status -= 1 + SSH.close() + return ue_ip_status + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + idx = 0 + for device_id in self.UEDevices: + if self.UEDevicesStatus[idx] != CONST.UE_STATUS_ATTACHED: + idx += 1 + continue + count = 0 + while count < 4: + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60) + result = re.search('inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', SSH.getBefore()) + if result is None: + logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') + time.sleep(1) + count += 1 + else: + count = 10 + if count < 9: + ue_ip_status -= 1 + continue + UE_IPAddress = result.group('ueipaddress') + logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') + for ueipaddress in self.UEIPAddresses: + if ueipaddress == UE_IPAddress: + logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') + ue_ip_status -= 1 + continue + self.UEIPAddresses.append(UE_IPAddress) + idx += 1 + SSH.close() + return ue_ip_status + + def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message): + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(message) + lock.release() + + def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue,EPC): + try: + SSH = sshconnection.SSHConnection() + # Launch ping on the EPC side (true for ltebox and old open-air-cn) + # But for OAI-Rel14-CUPS, we launch from python executor + launchFromEpc = True + if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): + launchFromEpc = False + ping_time = re.findall("-c (\d+)",str(self.ping_args)) + + if launchFromEpc: + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) + SSH.command('cd scripts', '\$', 5) + # In case of a docker-based deployment, we need to ping from the trf-gen container + launchFromTrfContainer = False + if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE): + launchFromTrfContainer = True + if launchFromTrfContainer: + ping_status = SSH.command('docker exec -it prod-trf-gen /bin/bash -c "ping ' + self.ping_args + ' ' + UE_IPAddress + '" 2>&1 | tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + else: + ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + #copy the ping log file to have it locally for analysis (ping stats) + SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.') + else: + #ping log file is on the python executor + cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' + message = cmd + '\n' + logging.debug(cmd) + ret = subprocess.run(cmd, shell=True) + ping_status = ret.returncode + #copy the ping log file to an other folder for log collection (source and destination are EPC) + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + #copy the ping log file to have it locally for analysis (ping stats) + logging.debug(EPC.SourceCodePath + 'ping_' + self.testCase_id + '_' + device_id + '.log') + SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath +'/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '.') + + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + #cat is executed on EPC + SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + #search is done on cat result + result = re.search(', (?P[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) + if result is None: + message = 'Packet Loss Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + packetloss = result.group('packetloss') + if float(packetloss) == 100: + message = 'Packet Loss is 100%' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + result = re.search('rtt min\/avg\/max\/mdev = (?P[0-9\.]+)\/(?P[0-9\.]+)\/(?P[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) + if result is None: + message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + rtt_min = result.group('rtt_min') + rtt_avg = result.group('rtt_avg') + rtt_max = result.group('rtt_max') + pal_msg = 'Packet Loss : ' + packetloss + '%' + min_msg = 'RTT(Min) : ' + rtt_min + ' ms' + avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' + max_msg = 'RTT(Max) : ' + rtt_max + ' ms' + lock.acquire() + logging.debug('\u001B[1;37;44m ping result (' + UE_IPAddress + ') \u001B[0m') + logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') + + #adding extra ping stats from local file + ping_log_file='ping_' + self.testCase_id + '_' + device_id + '.log' + logging.debug('Analyzing Ping log file : ' + os.getcwd() + '/' + ping_log_file) + ping_stat=GetPingTimeAnalysis(ping_log_file) + ping_stat_msg='' + if (ping_stat!=-1) and (len(ping_stat)!=0): + ping_stat_msg+='Ping stats before removing largest value : \n' + ping_stat_msg+='RTT(Min) : ' + str("{:.2f}".format(ping_stat['min_0'])) + 'ms \n' + ping_stat_msg+='RTT(Mean) : ' + str("{:.2f}".format(ping_stat['mean_0'])) + 'ms \n' + ping_stat_msg+='RTT(Median) : ' + str("{:.2f}".format(ping_stat['median_0'])) + 'ms \n' + ping_stat_msg+='RTT(Max) : ' + str("{:.2f}".format(ping_stat['max_0'])) + 'ms \n' + ping_stat_msg+='Max Index : ' + str(ping_stat['max_loc']) + '\n' + ping_stat_msg+='Ping stats after removing largest value : \n' + ping_stat_msg+='RTT(Min) : ' + str("{:.2f}".format(ping_stat['min_1'])) + 'ms \n' + ping_stat_msg+='RTT(Mean) : ' + str("{:.2f}".format(ping_stat['mean_1'])) + 'ms \n' + ping_stat_msg+='RTT(Median) : ' + str("{:.2f}".format(ping_stat['median_1'])) + 'ms \n' + ping_stat_msg+='RTT(Max) : ' + str("{:.2f}".format(ping_stat['max_1'])) + 'ms \n' + + #building html message + qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg + '\n' + ping_stat_msg + packetLossOK = True + if packetloss is not None: + if float(packetloss) > float(self.ping_packetloss_threshold): + qMsg += '\nPacket Loss too high' + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + packetLossOK = False + elif float(packetloss) > 0: + qMsg += '\nPacket Loss is not 0%' + logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') + if (packetLossOK): + statusQueue.put(0) + else: + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(qMsg) + lock.release() + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def PingNoS1_wrong_exit(self, qMsg,HTML): + html_queue = SimpleQueue() + html_cell = '
OAI UE ping result\n' + qMsg + '
' + html_queue.put(html_cell) + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + + def PingNoS1(self,HTML,RAN,EPC,COTS_UE): + SSH=sshconnection.SSHConnection() + check_eNB = True + check_OAI_UE = True + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) + if ping_from_eNB is not None: + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + else: + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + try: + if ping_from_eNB is not None: + SSH.open(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword) + SSH.command('cd ' + RAN.eNBSourceCodePath + '/cmake_targets/', '\$', 5) + else: + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) + ping_time = re.findall("-c (\d+)",str(self.ping_args)) + ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with OAI UE crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.PingNoS1_wrong_exit(message,HTML) + return + result = re.search(', (?P[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) + if result is None: + message = 'Packet Loss Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.PingNoS1_wrong_exit(message,HTML) + return + packetloss = result.group('packetloss') + if float(packetloss) == 100: + message = 'Packet Loss is 100%' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.PingNoS1_wrong_exit(message,HTML) + return + result = re.search('rtt min\/avg\/max\/mdev = (?P[0-9\.]+)\/(?P[0-9\.]+)\/(?P[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) + if result is None: + message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.PingNoS1_wrong_exit(message,HTML) + return + rtt_min = result.group('rtt_min') + rtt_avg = result.group('rtt_avg') + rtt_max = result.group('rtt_max') + pal_msg = 'Packet Loss : ' + packetloss + '%' + min_msg = 'RTT(Min) : ' + rtt_min + ' ms' + avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' + max_msg = 'RTT(Max) : ' + rtt_max + ' ms' + logging.debug('\u001B[1;37;44m OAI UE ping result \u001B[0m') + logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') + logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') + qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg + packetLossOK = True + if packetloss is not None: + if float(packetloss) > float(self.ping_packetloss_threshold): + qMsg += '\nPacket Loss too high' + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + packetLossOK = False + elif float(packetloss) > 0: + qMsg += '\nPacket Loss is not 0%' + logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') + SSH.close() + html_queue = SimpleQueue() + ip_addr = 'TBD' + html_cell = '
OAI UE ping result\n' + qMsg + '
' + html_queue.put(html_cell) + if packetLossOK: + HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) + else: + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + + # copying on the EPC server for logCollection + if ping_from_eNB is not None: + copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + else: + copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + if (copyin_res == 0): + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '.log', EPC.SourceCodePath + '/scripts') + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def Ping(self,HTML,RAN,EPC,COTS_UE): + result = re.search('noS1', str(RAN.Initialize_eNB_args)) + if result is not None: + self.PingNoS1(HTML,RAN,EPC,COTS_UE) + return + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + check_OAI_UE = True + else: + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + ueIpStatus = self.GetAllUEIPAddresses() + if (ueIpStatus < 0): + HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + multi_jobs = [] + i = 0 + lock = Lock() + status_queue = SimpleQueue() + for UE_IPAddress in self.UEIPAddresses: + device_id = self.UEDevices[i] + p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,EPC,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i = i + 1 + for job in multi_jobs: + job.join() + + if (status_queue.empty()): + HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + else: + ping_status = True + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + ping_status = False + device_id = status_queue.get() + ip_addr = status_queue.get() + message = status_queue.get() + html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' + html_queue.put(html_cell) + if (ping_status): + HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) + else: + HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def Iperf_ComputeTime(self): + result = re.search('-t (?P\d+)', str(self.iperf_args)) + if result is None: + logging.debug('\u001B[1;37;41m Iperf time Not Found! \u001B[0m') + sys.exit(1) + return result.group('iperf_time') + + def Iperf_ComputeModifiedBW(self, idx, ue_num): + result = re.search('-b (?P[0-9\.]+)[KMG]', str(self.iperf_args)) + if result is None: + logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') + sys.exit(1) + iperf_bandwidth = result.group('iperf_bandwidth') + if self.iperf_profile == 'balanced': + iperf_bandwidth_new = float(iperf_bandwidth)/ue_num + if self.iperf_profile == 'single-ue': + iperf_bandwidth_new = float(iperf_bandwidth) + if self.iperf_profile == 'unbalanced': + # residual is 2% of max bw + residualBW = float(iperf_bandwidth) / 50 + if idx == 0: + iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) + else: + iperf_bandwidth_new = residualBW + iperf_bandwidth_str = '-b ' + iperf_bandwidth + iperf_bandwidth_str_new = '-b ' + ('%.2f' % iperf_bandwidth_new) + result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args)) + if result is None: + logging.debug('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m') + sys.exit(1) + return result + + def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options,EPC,SSH): + + SSH.command('awk -f /tmp/tcp_iperf_stats.awk ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('Avg Bitrate : (?P[0-9\.]+ Mbits\/sec) Max Bitrate : (?P[0-9\.]+ Mbits\/sec) Min Bitrate : (?P[0-9\.]+ Mbits\/sec)', SSH.getBefore()) + if result is not None: + avgbitrate = result.group('average') + maxbitrate = result.group('maximum') + minbitrate = result.group('minimum') + lock.acquire() + logging.debug('\u001B[1;37;44m TCP iperf result (' + UE_IPAddress + ') \u001B[0m') + msg = 'TCP Stats :\n' + if avgbitrate is not None: + logging.debug('\u001B[1;34m Avg Bitrate : ' + avgbitrate + '\u001B[0m') + msg += 'Avg Bitrate : ' + avgbitrate + '\n' + if maxbitrate is not None: + logging.debug('\u001B[1;34m Max Bitrate : ' + maxbitrate + '\u001B[0m') + msg += 'Max Bitrate : ' + maxbitrate + '\n' + if minbitrate is not None: + logging.debug('\u001B[1;34m Min Bitrate : ' + minbitrate + '\u001B[0m') + msg += 'Min Bitrate : ' + minbitrate + '\n' + statusQueue.put(0) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(msg) + lock.release() + + return 0 + + def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options,EPC,SSH): + + result = re.search('-u', str(iperf_real_options)) + if result is None: + logging.debug('Into Iperf_analyzeV2TCPOutput client') + response = self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options,EPC,SSH) + logging.debug('Iperf_analyzeV2TCPOutput response returned value = ' + str(response)) + return response + + result = re.search('Server Report:', SSH.getBefore()) + if result is None: + result = re.search('read failed: Connection refused', SSH.getBefore()) + if result is not None: + logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m') + else: + logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') + return -1 + # Computing the requested bandwidth in float + result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) + if result is not None: + req_bandwidth = result.group('iperf_bandwidth') + req_bw = float(req_bandwidth) + result = re.search('-b [0-9\.]+K', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Kbits/sec' % req_bw + req_bw = req_bw * 1000 + result = re.search('-b [0-9\.]+M', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Mbits/sec' % req_bw + req_bw = req_bw * 1000000 + result = re.search('-b [0-9\.]+G', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Gbits/sec' % req_bw + req_bw = req_bw * 1000000000 + + result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P[0-9\.]+)%\))', SSH.getBefore()) + if result is not None: + bitrate = result.group('bitrate') + packetloss = result.group('packetloss') + jitter = result.group('jitter') + lock.acquire() + logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') + iperfStatus = True + msg = 'Req Bitrate : ' + req_bandwidth + '\n' + logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m') + if bitrate is not None: + msg += 'Bitrate : ' + bitrate + '\n' + logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') + result = re.search('(?P[0-9\.]+) [KMG]bits/sec', str(bitrate)) + if result is not None: + actual_bw = float(str(result.group('real_bw'))) + result = re.search('[0-9\.]+ K', bitrate) + if result is not None: + actual_bw = actual_bw * 1000 + result = re.search('[0-9\.]+ M', bitrate) + if result is not None: + actual_bw = actual_bw * 1000000 + result = re.search('[0-9\.]+ G', bitrate) + if result is not None: + actual_bw = actual_bw * 1000000000 + br_loss = 100 * actual_bw / req_bw + bitperf = '%.2f ' % br_loss + msg += 'Bitrate Perf: ' + bitperf + '%\n' + logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m') + if packetloss is not None: + msg += 'Packet Loss : ' + packetloss + '%\n' + logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') + if float(packetloss) > float(self.iperf_packetloss_threshold): + msg += 'Packet Loss too high!\n' + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + iperfStatus = False + if jitter is not None: + msg += 'Jitter : ' + jitter + '\n' + logging.debug('\u001B[1;34m Jitter : ' + jitter + '\u001B[0m') + if (iperfStatus): + statusQueue.put(0) + else: + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(msg) + lock.release() + return 0 + else: + return -2 + + def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): + if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') + return + # Computing the requested bandwidth in float + result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) + if result is None: + logging.debug('Iperf bandwidth Not Found!') + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!') + return + else: + req_bandwidth = result.group('iperf_bandwidth') + req_bw = float(req_bandwidth) + result = re.search('-b [0-9\.]+K', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Kbits/sec' % req_bw + req_bw = req_bw * 1000 + result = re.search('-b [0-9\.]+M', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Mbits/sec' % req_bw + req_bw = req_bw * 1000000 + result = re.search('-b [0-9\.]+G', str(iperf_real_options)) + if result is not None: + req_bandwidth = '%.1f Gbits/sec' % req_bw + req_bw = req_bw * 1000000000 + + server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') + br_sum = 0.0 + ji_sum = 0.0 + pl_sum = 0 + ps_sum = 0 + row_idx = 0 + for line in server_file.readlines(): + result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(?P[0-9]+)/ +(?P[0-9]+)', str(line)) + if result is not None: + bitrate = result.group('bitrate') + jitter = result.group('jitter') + packetlost = result.group('lostPack') + packetsent = result.group('sentPack') + br = bitrate.split(' ') + ji = jitter.split(' ') + row_idx = row_idx + 1 + curr_br = float(br[0]) + pl_sum = pl_sum + int(packetlost) + ps_sum = ps_sum + int(packetsent) + if (br[1] == 'Kbits/sec'): + curr_br = curr_br * 1000 + if (br[1] == 'Mbits/sec'): + curr_br = curr_br * 1000 * 1000 + br_sum = curr_br + br_sum + ji_sum = float(ji[0]) + ji_sum + if (row_idx > 0): + br_sum = br_sum / row_idx + ji_sum = ji_sum / row_idx + br_loss = 100 * br_sum / req_bw + if (br_sum > 1000): + br_sum = br_sum / 1000 + if (br_sum > 1000): + br_sum = br_sum / 1000 + bitrate = '%.2f Mbits/sec' % br_sum + else: + bitrate = '%.2f Kbits/sec' % br_sum + else: + bitrate = '%.2f bits/sec' % br_sum + bitperf = '%.2f ' % br_loss + bitperf += '%' + jitter = '%.2f ms' % (ji_sum) + if (ps_sum > 0): + pl = float(100 * pl_sum / ps_sum) + packetloss = '%2.1f ' % (pl) + packetloss += '%' + else: + packetloss = 'unknown' + lock.acquire() + if (br_loss < 90): + statusQueue.put(1) + else: + statusQueue.put(0) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + req_msg = 'Req Bitrate : ' + req_bandwidth + bir_msg = 'Bitrate : ' + bitrate + brl_msg = 'Bitrate Perf: ' + bitperf + jit_msg = 'Jitter : ' + jitter + pal_msg = 'Packet Loss : ' + packetloss + statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n') + logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m') + logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m') + logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') + lock.release() + else: + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') + + server_file.close() + + + def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue,SSH): + + result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore()) + if result is None: + result = re.search('(?Piperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore()) + lock.acquire() + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + if result is not None: + logging.debug('\u001B[1;37;41m ' + result.group('error') + ' \u001B[0m') + statusQueue.put(result.group('error')) + else: + logging.debug('\u001B[1;37;41m Bitrate and/or Packet Loss Not Found! \u001B[0m') + statusQueue.put('Bitrate and/or Packet Loss Not Found!') + lock.release() + + bitrate = result.group('bitrate') + packetloss = result.group('packetloss') + lock.acquire() + logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') + logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') + msg = 'Bitrate : ' + bitrate + '\n' + iperfStatus = True + if packetloss is not None: + logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') + msg += 'Packet Loss : ' + packetloss + '%\n' + if float(packetloss) > float(self.iperf_packetloss_threshold): + logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') + msg += 'Packet Loss too high!\n' + iperfStatus = False + if (iperfStatus): + statusQueue.put(0) + else: + statusQueue.put(-1) + statusQueue.put(device_id) + statusQueue.put(UE_IPAddress) + statusQueue.put(msg) + lock.release() + + def Iperf_UL_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC): + SSH = sshconnection.SSHConnection() + udpIperf = True + result = re.search('-u', str(self.iperf_args)) + if result is None: + udpIperf = False + ipnumbers = UE_IPAddress.split('.') + if (len(ipnumbers) == 4): + ipnumbers[3] = '1' + EPC_Iperf_UE_IPAddress = ipnumbers[0] + '.' + ipnumbers[1] + '.' + ipnumbers[2] + '.' + ipnumbers[3] + + # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 + # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address + launchFromEpc = True + if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): + launchFromEpc = False + cmd = 'hostname -I' + ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') + if ret.stdout is not None: + EPC_Iperf_UE_IPAddress = ret.stdout.strip() + # When using a docker-based deployment, IPERF client shall be launched from trf container + launchFromTrfContainer = False + if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE): + launchFromTrfContainer = True + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('docker inspect --format="TRF_IP_ADDR = {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" prod-trf-gen', '\$', 5) + result = re.search('TRF_IP_ADDR = (?P[0-9\.]+)', SSH.getBefore()) + if result is not None: + EPC_Iperf_UE_IPAddress = result.group('trf_ip_addr') + SSH.close() + port = 5001 + idx + udpOptions = '' + if udpIperf: + udpOptions = '-u ' + if launchFromEpc: + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) + SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + if launchFromTrfContainer: + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' + else: + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/iperf-2.0.5/bin/' + SSH.command('docker exec -d prod-trf-gen /bin/bash -c "nohup ' + prefix + 'iperf ' + udpOptions + '-s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &"', '\$', 5) + else: + SSH.command('echo $USER; nohup iperf ' + udpOptions + '-s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5) + SSH.close() + else: + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' + else: + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/opt/iperf-2.0.5/bin/' + cmd = 'nohup ' + prefix + 'iperf ' + udpOptions + '-s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' + logging.debug(cmd) + subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') + time.sleep(0.5) + + # Launch iperf client on UE + if (device_id == 'OAI-UE'): + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) + else: + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + SSH.command('cd ' + EPC.SourceCodePath+ '/scripts', '\$', 5) + iperf_time = self.Iperf_ComputeTime() + time.sleep(0.5) + + if udpIperf: + modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) + else: + modified_options = str(self.iperf_args) + modified_options = modified_options.replace('-R','') + time.sleep(0.5) + + SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + if (device_id == 'OAI-UE'): + iperf_status = SSH.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + if self.ADBCentralized: + iperf_status = SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + iperf_status = SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + SSH.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + SSH.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + # TIMEOUT Case + if iperf_status < 0: + SSH.close() + message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options,EPC,SSH) + SSH.close() + + # Kill iperf server on EPC side + if launchFromEpc: + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + if launchFromTrfContainer: + SSH.command('docker exec -it prod-trf-gen /bin/bash -c "killall --signal SIGKILL iperf"', '\$', 5) + else: + SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5) + SSH.close() + else: + cmd = 'killall --signal SIGKILL iperf' + logging.debug(cmd) + subprocess.run(cmd, shell=True) + time.sleep(1) + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + # in case of failure, retrieve server log + if (clientStatus == -1) or (clientStatus == -2): + if launchFromEpc: + time.sleep(1) + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') + if launchFromTrfContainer: + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('docker cp prod-trf-gen:/iperf-2.0.5/iperf_server_' + self.testCase_id + '_' + device_id + '.log ' + EPC.SourceCodePath + '/scripts', '\$', 5) + SSH.close() + SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) + # in case of OAI-UE + if (device_id == 'OAI-UE'): + SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + + def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC): + try: + SSH = sshconnection.SSHConnection() + # Single-UE profile -- iperf only on one UE + if self.iperf_profile == 'single-ue' and idx != 0: + return + useIperf3 = False + udpIperf = True + + self.ueIperfVersion = '2.0.5' + if (device_id != 'OAI-UE'): + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it + SSH.command('if [ ! -d ' + EPC.SourceCodePath + '/scripts ]; then mkdir -p ' + EPC.SourceCodePath + '/scripts ; fi', '\$', 5) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) + # Checking if iperf / iperf3 are installed + if self.ADBCentralized: + SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) + # DEBUG: disabling iperf3 usage for the moment + result = re.search('iperf4', SSH.getBefore()) + if result is None: + result = re.search('iperf', SSH.getBefore()) + if result is None: + message = 'Neither iperf nor iperf3 installed on UE!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + SSH.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + else: + if self.ADBCentralized: + SSH.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60) + result = re.search('iperf version 2.0.5', SSH.getBefore()) + if result is not None: + self.ueIperfVersion = '2.0.5' + result = re.search('iperf version 2.0.10', SSH.getBefore()) + if result is not None: + self.ueIperfVersion = '2.0.10' + else: + useIperf3 = True + SSH.close() + else: + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('iperf --version', '\$', 5) + result = re.search('iperf version 2.0.5', SSH.getBefore()) + if result is not None: + self.ueIperfVersion = '2.0.5' + result = re.search('iperf version 2.0.10', SSH.getBefore()) + if result is not None: + self.ueIperfVersion = '2.0.10' + SSH.close() + # in case of iperf, UL has its own function + if (not useIperf3): + result = re.search('-R', str(self.iperf_args)) + if result is not None: + self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC) + return + + # Launch the IPERF server on the UE side for DL + if (device_id == 'OAI-UE'): + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) + SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('-u', str(self.iperf_args)) + if result is None: + SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) + udpIperf = False + else: + SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) + else: + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) + if self.ADBCentralized: + if (useIperf3): + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) + else: + SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('-u', str(self.iperf_args)) + if result is None: + SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + udpIperf = False + else: + SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + else: + SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + SSH.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60) + + time.sleep(0.5) + SSH.close() + + # Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn + # But for OAI-Rel14-CUPS, we launch from python executor + launchFromEpc = True + if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): + launchFromEpc = False + # When using a docker-based deployment, IPERF client shall be launched from trf container + launchFromTrfContainer = False + if re.match('OAI-Rel14-Docker', EPC.Type, re.IGNORECASE): + launchFromTrfContainer = True + if launchFromEpc: + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) + iperf_time = self.Iperf_ComputeTime() + time.sleep(0.5) + + if udpIperf: + modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) + else: + modified_options = str(self.iperf_args) + time.sleep(0.5) + + if launchFromEpc: + SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + else: + if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log') + if (useIperf3): + SSH.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + + clientStatus = 0 + self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue,SSH) + else: + if launchFromEpc: + if launchFromTrfContainer: + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' + else: + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/iperf-2.0.5/bin/' + iperf_status = SSH.command('docker exec -it prod-trf-gen /bin/bash -c "' + prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + '" 2>&1 | tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + iperf_status = SSH.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + if self.ueIperfVersion == self.dummyIperfVersion: + prefix = '' + else: + prefix = '' + if self.ueIperfVersion == '2.0.5': + prefix = '/opt/iperf-2.0.5/bin/' + cmd = prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log' + message = cmd + '\n' + logging.debug(cmd) + ret = subprocess.run(cmd, shell=True) + iperf_status = ret.returncode + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cat ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + if iperf_status < 0: + if launchFromEpc: + SSH.close() + message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + logging.debug('Into Iperf_analyzeV2Output client') + clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options, EPC,SSH) + logging.debug('Iperf_analyzeV2Output clientStatus returned value = ' + str(clientStatus)) + SSH.close() + + # Kill the IPERF server that runs in background + if (device_id == 'OAI-UE'): + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('killall iperf', '\$', 5) + else: + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60) + result = re.search('shell +(?P\d+)', SSH.getBefore()) + if result is not None: + pid_iperf = result.group('pid') + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) + SSH.close() + # if the client report is absent, try to analyze the server log file + if (clientStatus == -1): + time.sleep(1) + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') + if (device_id == 'OAI-UE'): + SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + else: + SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.SourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + # fromdos has to be called on the python executor not on ADB server + cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 > /dev/null' + try: + subprocess.run(cmd, shell=True) + except: + pass + cmd = 'dos2unix -o iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 > /dev/null' + try: + subprocess.run(cmd, shell=True) + except: + pass + self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) + + # in case of OAI UE: + if (device_id == 'OAI-UE'): + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + if not launchFromEpc: + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + else: + SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def IperfNoS1(self,HTML,RAN,EPC,COTS_UE): + SSH = sshconnection.SSHConnection() + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + check_OAI_UE = True + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + server_on_enb = re.search('-R', str(self.iperf_args)) + if server_on_enb is not None: + iServerIPAddr = RAN.eNBIPAddress + iServerUser = RAN.eNBUserName + iServerPasswd = RAN.eNBPassword + iClientIPAddr = self.UEIPAddress + iClientUser = self.UEUserName + iClientPasswd = self.UEPassword + else: + iServerIPAddr = self.UEIPAddress + iServerUser = self.UEUserName + iServerPasswd = self.UEPassword + iClientIPAddr = RAN.eNBIPAddress + iClientUser = RAN.eNBUserName + iClientPasswd = RAN.eNBPassword + if self.iperf_options != 'sink': + # Starting the iperf server + SSH.open(iServerIPAddr, iServerUser, iServerPasswd) + # args SHALL be "-c client -u any" + # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 + # -B 10.0.1.1 -u -s -i 1 -fm + server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) + server_options = server_options.replace('-c','-B') + SSH.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) + SSH.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) + time.sleep(0.5) + SSH.close() + + # Starting the iperf client + modified_options = self.Iperf_ComputeModifiedBW(0, 1) + modified_options = modified_options.replace('-R','') + iperf_time = self.Iperf_ComputeTime() + SSH.open(iClientIPAddr, iClientUser, iClientPasswd) + SSH.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) + iperf_status = SSH.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) + status_queue = SimpleQueue() + lock = Lock() + if iperf_status < 0: + message = 'iperf on OAI UE crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + clientStatus = -2 + else: + if self.iperf_options == 'sink': + clientStatus = 0 + status_queue.put(0) + status_queue.put('OAI-UE') + status_queue.put('10.0.1.2') + status_queue.put('Sink Test : no check') + else: + clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options, EPC,SSH) + SSH.close() + + # Stopping the iperf server + if self.iperf_options != 'sink': + SSH.open(iServerIPAddr, iServerUser, iServerPasswd) + SSH.command('killall --signal SIGKILL iperf', '\$', 5) + time.sleep(0.5) + SSH.close() + + if (clientStatus == -1): + if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '.log') + SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) + + # copying on the EPC server for logCollection + if (clientStatus == -1): + copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts') + copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts') + iperf_noperf = False + if status_queue.empty(): + iperf_status = False + else: + iperf_status = True + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + iperf_status = False + if (count > 0): + iperf_noperf = True + device_id = status_queue.get() + ip_addr = status_queue.get() + message = status_queue.get() + html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' + html_queue.put(html_cell) + if (iperf_noperf and iperf_status): + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + elif (iperf_status): + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) + else: + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def Iperf(self,HTML,RAN,EPC,COTS_UE): + result = re.search('noS1', str(RAN.Initialize_eNB_args)) + if result is not None: + self.IperfNoS1(HTML,RAN,EPC,COTS_UE) + return + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + check_eNB = True + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + check_OAI_UE = True + else: + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + if (pStatus < 0): + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + ueIpStatus = self.GetAllUEIPAddresses() + if (ueIpStatus < 0): + logging.debug('going here') + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + return + + self.dummyIperfVersion = '2.0.10' + #cmd = 'iperf --version' + #logging.debug(cmd + '\n') + #iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True) + #result = re.search('iperf version 2.0.5', str(iperfStdout.strip())) + #if result is not None: + # dummyIperfVersion = '2.0.5' + #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) + #if result is not None: + # dummyIperfVersion = '2.0.10' + + multi_jobs = [] + i = 0 + ue_num = len(self.UEIPAddresses) + lock = Lock() + status_queue = SimpleQueue() + for UE_IPAddress in self.UEIPAddresses: + device_id = self.UEDevices[i] + p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,EPC,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i = i + 1 + for job in multi_jobs: + job.join() + + if (status_queue.empty()): + HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + else: + iperf_status = True + iperf_noperf = False + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + iperf_status = False + if (count > 0): + iperf_noperf = True + device_id = status_queue.get() + ip_addr = status_queue.get() + message = status_queue.get() + html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' + html_queue.put(html_cell) + if (iperf_noperf and iperf_status): + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + elif (iperf_status): + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) + else: + HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + + def CheckProcessExist(self, check_eNB, check_OAI_UE,RAN,EPC): + multi_jobs = [] + status_queue = SimpleQueue() + # in noS1 config, no need to check status from EPC + # in gNB also currently no need to check + result = re.search('noS1|band78', str(RAN.Initialize_eNB_args)) + if result is None: + p = Process(target = EPC.CheckHSSProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + p = Process(target = EPC.CheckMMEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + p = Process(target = EPC.CheckSPGWProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + else: + if (check_eNB == False) and (check_OAI_UE == False): + return 0 + if check_eNB: + p = Process(target = RAN.CheckeNBProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + if check_OAI_UE: + p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + for job in multi_jobs: + job.join() + + if (status_queue.empty()): + return -15 + else: + result = 0 + while (not status_queue.empty()): + status = status_queue.get() + if (status < 0): + result = status + if result == CONST.ENB_PROCESS_FAILED: + fileCheck = re.search('enb_', str(RAN.eNBLogFiles[0])) + if fileCheck is not None: + SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/' + RAN.eNBLogFiles[0], '.') + logStatus = RAN.AnalyzeLogFile_eNB(RAN.eNBLogFiles[0]) + if logStatus < 0: + result = logStatus + RAN.eNBLogFiles[0]='' + if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: + self.TerminateFlexranCtrl() + return result + + def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag,HTML,RAN): + multi_jobs = [] + status_queue = SimpleQueue() + if initialize_OAI_UE_flag == False: + p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + for job in multi_jobs: + job.join() + + if (status_queue.empty()): + return -15 + else: + result = 0 + while (not status_queue.empty()): + status = status_queue.get() + if (status < 0): + result = status + if result == CONST.OAI_UE_PROCESS_FAILED: + fileCheck = re.search('ue_', str(self.UELogFile)) + if fileCheck is not None: + SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') + logStatus = self.AnalyzeLogFile_UE(self.UELogFile,HTML,RAN) + if logStatus < 0: + result = logStatus + return result + + def CheckOAIUEProcess(self, status_queue): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + ' | grep -v grep', '\$', 5) + result = re.search(self.air_interface, SSH.getBefore()) + if result is None: + logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') + status_queue.put(CONST.OAI_UE_PROCESS_FAILED) + else: + status_queue.put(CONST.OAI_UE_PROCESS_OK) + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + + def AnalyzeLogFile_UE(self, UElogFile,HTML,RAN): + if (not os.path.isfile('./' + UElogFile)): + return -1 + ue_log_file = open('./' + UElogFile, 'r') + exitSignalReceived = False + foundAssertion = False + msgAssertion = '' + msgLine = 0 + foundSegFault = False + foundRealTimeIssue = False + uciStatMsgCount = 0 + pdcpDataReqFailedCount = 0 + badDciCount = 0 + f1aRetransmissionCount = 0 + fatalErrorCount = 0 + macBsrTimerExpiredCount = 0 + rrcConnectionRecfgComplete = 0 + no_cell_sync_found = False + mib_found = False + frequency_found = False + plmn_found = False + nrUEFlag = False + nrDecodeMib = 0 + nrFoundDCI = 0 + nrCRCOK = 0 + mbms_messages = 0 + HTML.htmlUEFailureMsg='' + global_status = CONST.ALL_PROCESSES_OK + for line in ue_log_file.readlines(): + result = re.search('nr_synchro_time', str(line)) + if result is not None: + nrUEFlag = True + if nrUEFlag: + result = re.search('decode mib', str(line)) + if result is not None: + nrDecodeMib += 1 + result = re.search('found 1 DCIs', str(line)) + if result is not None: + nrFoundDCI += 1 + result = re.search('CRC OK', str(line)) + if result is not None: + nrCRCOK += 1 + result = re.search('Exiting OAI softmodem', str(line)) + if result is not None: + exitSignalReceived = True + result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('[Cc]ore [dD]ump', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('./lte-uesoftmodem', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('[Aa]ssertion', str(line)) + if result is not None and not exitSignalReceived: + foundAssertion = True + result = re.search('LLL', str(line)) + if result is not None and not exitSignalReceived: + foundRealTimeIssue = True + if foundAssertion and (msgLine < 3): + msgLine += 1 + msgAssertion += str(line) + result = re.search('uci->stat', str(line)) + if result is not None and not exitSignalReceived: + uciStatMsgCount += 1 + result = re.search('PDCP data request failed', str(line)) + if result is not None and not exitSignalReceived: + pdcpDataReqFailedCount += 1 + result = re.search('bad DCI 1', str(line)) + if result is not None and not exitSignalReceived: + badDciCount += 1 + result = re.search('Format1A Retransmission but TBS are different', str(line)) + if result is not None and not exitSignalReceived: + f1aRetransmissionCount += 1 + result = re.search('FATAL ERROR', str(line)) + if result is not None and not exitSignalReceived: + fatalErrorCount += 1 + result = re.search('MAC BSR Triggered ReTxBSR Timer expiry', str(line)) + if result is not None and not exitSignalReceived: + macBsrTimerExpiredCount += 1 + result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) + if result is not None: + rrcConnectionRecfgComplete += 1 + # No cell synchronization found, abandoning + result = re.search('No cell synchronization found, abandoning', str(line)) + if result is not None: + no_cell_sync_found = True + if RAN.eNBmbmsEnables[0]: + result = re.search('TRIED TO PUSH MBMS DATA', str(line)) + if result is not None: + mbms_messages += 1 + result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P\d{1,3}), N_RB_DL (?P\d{1,3}), PHICH DURATION (?P\d), PHICH RESOURCE (?P.{1,4}), TX_ANT (?P\d)", str(line)) + if result is not None and (not mib_found): + try: + mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " nidcell = " + result.group('nidcell') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " n_rb_dl = " + result.group('n_rb_dl') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " phich_duration = " + result.group('phich_duration') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " phich_resource = " + result.group('phich_resource') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mibMsg = " tx_ant = " + result.group('tx_ant') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + mib_found = True + except Exception as e: + logging.error('\033[91m' + "MIB marker was not found" + '\033[0m') + result = re.search("Measured Carrier Frequency (?P\d{1,15}) Hz", str(line)) + if result is not None and (not frequency_found): + try: + mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + frequency_found = True + except Exception as e: + logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m') + result = re.search("PLMN MCC (?P\d{1,3}), MNC (?P\d{1,3}), TAC", str(line)) + if result is not None and (not plmn_found): + try: + mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + plmn_found = True + except Exception as e: + logging.error('\033[91m' + "PLMN not found" + '\033[0m') + result = re.search("Found (?P[\w,\s]{1,15}) \(name from internal table\)", str(line)) + if result is not None: + try: + mibMsg = "The operator is: " + result.group('operator') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + except Exception as e: + logging.error('\033[91m' + "Operator name not found" + '\033[0m') + result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) + if result is not None: + try: + mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + ' -> ' + logging.debug('\033[94m' + mibMsg + '\033[0m') + except Exception as e: + logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') + result = re.search("DL Carrier Frequency/ARFCN : \-*(?P\d{1,15}/\d{1,4})", str(line)) + if result is not None: + try: + freq = result.group('carrier_frequency') + new_freq = re.sub('/[0-9]+','',freq) + float_freq = float(new_freq) / 1000000 + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' + logging.debug('\033[94m' + " DL Carrier Frequency is: " + str(freq) + '\033[0m') + except Exception as e: + logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') + result = re.search("AllowedMeasBandwidth : (?P\d{1,7})", str(line)) + if result is not None: + try: + prb = result.group('allowed_bandwidth') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + ' -- PRB: ' + prb + '\n' + logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') + except Exception as e: + logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') + ue_log_file.close() + if rrcConnectionRecfgComplete > 0: + statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' + logging.debug('\033[94m' + statMsg + '\033[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if nrUEFlag: + if nrDecodeMib > 0: + statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if nrFoundDCI > 0: + statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if nrCRCOK > 0: + statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if not frequency_found: + statMsg = 'NR-UE could NOT synch!' + logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if uciStatMsgCount > 0: + statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if pdcpDataReqFailedCount > 0: + statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if badDciCount > 0: + statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if f1aRetransmissionCount > 0: + statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if fatalErrorCount > 0: + statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if macBsrTimerExpiredCount > 0: + statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if RAN.eNBmbmsEnables[0]: + if mbms_messages > 0: + statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + else: + statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' + logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m') + global_status = CONST.OAI_UE_PROCESS_NO_MBMS_MSGS + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' + if foundSegFault: + logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') + if not nrUEFlag: + global_status = CONST.OAI_UE_PROCESS_SEG_FAULT + else: + if not frequency_found: + global_status = CONST.OAI_UE_PROCESS_SEG_FAULT + if foundAssertion: + logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE showed an assertion!\n' + if not nrUEFlag: + if not mib_found or not frequency_found: + global_status = CONST.OAI_UE_PROCESS_ASSERTION + else: + if not frequency_found: + global_status = CONST.OAI_UE_PROCESS_ASSERTION + if foundRealTimeIssue: + logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE faced real time issues!\n' + if nrUEFlag: + if not frequency_found: + global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC + else: + if no_cell_sync_found and not mib_found: + logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE could not synchronize!\n' + global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC + return global_status + + + def TerminateFlexranCtrl(self,HTML,RAN,EPC): + if RAN.flexranCtrlInstalled == False or RAN.flexranCtrlStarted == False: + return + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) + time.sleep(1) + SSH.command('echo ' + EPC.Password + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) + time.sleep(1) + SSH.close() + RAN.flexranCtrlStarted=False + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def TerminateUE_common(self, device_id, idx,COTS_UE): + try: + SSH = sshconnection.SSHConnection() + SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # back in airplane mode on (ie radio off) + if self.ADBCentralized: + #RH quick add on to intgrate cots control defined by yaml + #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class + #otherwise we use the legacy procedure + if COTS_UE.Check_Exists(device_id): + #switch device to Airplane mode ON (ie Radio OFF) + COTS_UE.Set_Airplane(device_id, 'ON') + elif device_id == '84B7N16418004022': + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) + else: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) + logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') + + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60) + result = re.search('shell +(?P\d+)', SSH.getBefore()) + if result is not None: + pid_iperf = result.group('pid') + if self.ADBCentralized: + SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5) + else: + SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) + SSH.close() + except: + os.kill(os.getppid(),signal.SIGUSR1) + + def TerminateUE(self,HTML,COTS_UE): + terminate_ue_flag = False + self.GetAllUEDevices(terminate_ue_flag) + multi_jobs = [] + i = 0 + for device_id in self.UEDevices: + p = Process(target= self.TerminateUE_common, args = (device_id,i,COTS_UE,)) + p.daemon = True + p.start() + multi_jobs.append(p) + i += 1 + for job in multi_jobs: + job.join() + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def TerminateOAIUE(self,HTML,RAN,COTS_UE,EPC): + SSH = sshconnection.SSHConnection() + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) + SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('-uesoftmodem', SSH.getBefore()) + if result is not None: + SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT -r .*-uesoftmodem || true', '\$', 5) + time.sleep(10) + SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('-uesoftmodem', SSH.getBefore()) + if result is not None: + SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL -r .*-uesoftmodem || true', '\$', 5) + time.sleep(5) + SSH.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + SSH.close() + result = re.search('ue_', str(self.UELogFile)) + if result is not None: + copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') + if (copyin_res == -1): + logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') + HTML.htmlUEFailureMsg='Could not copy UE logfile to analyze it!' + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') + self.UELogFile = '' + return + logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_UE(self.UELogFile,HTML,RAN) + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is not None: + ueAction = 'Sniffing' + else: + ueAction = 'Connection' + if (logStatus < 0): + logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') + HTML.htmlUEFailureMsg='' + ueAction + ' Failed\n' + HTML.htmlUEFailureMsg + HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') + if self.air_interface == 'lte-uesoftmodem': + # In case of sniffing on commercial eNBs we have random results + # Not an error then + if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): + self.Initialize_OAI_UE_args = '' + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + else: + if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC): + self.Initialize_OAI_UE_args = '' + self.AutoTerminateUEandeNB(HTML,RAN,COTS_UE,EPC) + else: + logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') + HTML.htmlUEFailureMsg='' + ueAction + ' Completed\n' + HTML.htmlUEFailureMsg + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + self.UELogFile = '' + else: + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def AutoTerminateUEandeNB(self,HTML,RAN,COTS_UE,EPC): + if (self.ADBIPAddress != 'none'): + self.testCase_id = 'AUTO-KILL-UE' + HTML.testCase_id=self.testCase_id + self.desc = 'Automatic Termination of UE' + HTML.desc='Automatic Termination of UE' + self.ShowTestID() + self.TerminateUE(HTML,COTS_UE) + if (self.Initialize_OAI_UE_args != ''): + self.testCase_id = 'AUTO-KILL-OAI-UE' + HTML.testCase_id=self.testCase_id + self.desc = 'Automatic Termination of OAI-UE' + HTML.desc='Automatic Termination of OAI-UE' + self.ShowTestID() + self.TerminateOAIUE(HTML,RAN,COTS_UE,EPC) + if (RAN.Initialize_eNB_args != ''): + self.testCase_id = 'AUTO-KILL-RAN' + HTML.testCase_id=self.testCase_id + self.desc = 'Automatic Termination of all RAN nodes' + HTML.desc='Automatic Termination of RAN nodes' + self.ShowTestID() + #terminate all RAN nodes eNB/gNB/OCP + for instance in range(0, len(RAN.air_interface)): + if RAN.air_interface[instance]!='': + logging.debug('Auto Termination of Instance ' + str(instance) + ' : ' + RAN.air_interface[instance]) + RAN.eNB_instance=instance + RAN.TerminateeNB(HTML,EPC) + if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: + self.testCase_id = 'AUTO-KILL-flexran-ctl' + HTML.testCase_id=self.testCase_id + self.desc = 'Automatic Termination of FlexRan CTL' + HTML.desc='Automatic Termination of FlexRan CTL' + self.ShowTestID() + self.TerminateFlexranCtrl(HTML,RAN,EPC) + RAN.prematureExit=True + + def IdleSleep(self,HTML): + time.sleep(self.idle_sleep_time) + HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK) + + def X2_Status(self, idx, fileName): + cmd = "curl --silent http://" + EPC.IPAddress + ":9999/stats | jq '.' > " + fileName + message = cmd + '\n' + logging.debug(cmd) + subprocess.run(cmd, shell=True) + if idx == 0: + cmd = "jq '.mac_stats | length' " + fileName + strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True) + self.x2NbENBs = int(strNbEnbs.strip()) + cnt = 0 + while cnt < self.x2NbENBs: + cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName + bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True) + self.x2ENBBsIds[idx].append(bs_id.strip()) + cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName + stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True) + nbUEs = int(stNbUEs.strip()) + ueIdx = 0 + self.x2ENBConnectedUEs[idx].append([]) + while ueIdx < nbUEs: + cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName + rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True) + self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip()) + ueIdx += 1 + cnt += 1 + + msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)" + logging.debug(msg) + message += msg + '\n' + cnt = 0 + while cnt < self.x2NbENBs: + msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][cnt])) + " UE(s)" + logging.debug(msg) + message += msg + '\n' + ueIdx = 0 + while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]): + msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx]) + logging.debug(msg) + message += msg + '\n' + ueIdx += 1 + cnt += 1 + return message + + def Perform_X2_Handover(self,HTML,RAN,EPC): + html_queue = SimpleQueue() + fullMessage = '
'
+		msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options
+		logging.debug(msg)
+		fullMessage += msg + '\n'
+		if self.x2_ho_options == 'network':
+			if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
+				self.x2ENBBsIds = []
+				self.x2ENBConnectedUEs = []
+				self.x2ENBBsIds.append([])
+				self.x2ENBBsIds.append([])
+				self.x2ENBConnectedUEs.append([])
+				self.x2ENBConnectedUEs.append([])
+				fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json') 
+
+				msg = "Activating the X2 Net control on each eNB"
+				logging.debug(msg)
+				fullMessage += msg + '\n'
+				eNB_cnt = self.x2NbENBs
+				cnt = 0
+				while cnt < eNB_cnt:
+					cmd = "curl -XPOST http://" + EPC.IPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
+					logging.debug(cmd)
+					fullMessage += cmd + '\n'
+					subprocess.run(cmd, shell=True)
+					cnt += 1
+				# Waiting for the activation to be active
+				time.sleep(10)
+				msg = "Switching UE(s) from eNB to eNB"
+				logging.debug(msg)
+				fullMessage += msg + '\n'
+				cnt = 0
+				while cnt < eNB_cnt:
+					ueIdx = 0
+					while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]):
+						cmd = "curl -XPOST http://" + EPC.IPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
+						logging.debug(cmd)
+						fullMessage += cmd + '\n'
+						subprocess.run(cmd, shell=True)
+						ueIdx += 1
+					cnt += 1
+				time.sleep(10)
+				# check
+				logging.debug("Checking the Status after X2 Handover")
+				fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json') 
+				cnt = 0
+				x2Status = True
+				while cnt < eNB_cnt:
+					if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]):
+						x2Status = False
+					cnt += 1
+				if x2Status:
+					msg = "X2 Handover was successful"
+					logging.debug(msg)
+					fullMessage += msg + '
' + html_queue.put(fullMessage) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + else: + msg = "X2 Handover FAILED" + logging.error(msg) + fullMessage += msg + '' + html_queue.put(fullMessage) + HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + else: + HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK) + + def LogCollectBuild(self,RAN): + SSH = sshconnection.SSHConnection() + if (RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != ''): + IPAddress = RAN.eNBIPAddress + UserName = RAN.eNBUserName + Password = RAN.eNBPassword + SourceCodePath = RAN.eNBSourceCodePath + elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): + IPAddress = self.UEIPAddress + UserName = self.UEUserName + Password = self.UEPassword + SourceCodePath = self.UESourceCodePath + else: + sys.exit('Insufficient Parameter') + SSH.open(IPAddress, UserName, Password) + SSH.command('cd ' + SourceCodePath, '\$', 5) + SSH.command('cd cmake_targets', '\$', 5) + SSH.command('rm -f build.log.zip', '\$', 5) + SSH.command('zip -r build.log.zip build_log_*/*', '\$', 60) + SSH.close() + + def LogCollectPing(self,EPC): + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) + SSH.command('cd scripts', '\$', 5) + SSH.command('rm -f ping.log.zip', '\$', 5) + SSH.command('zip ping.log.zip ping*.log', '\$', 60) + SSH.command('rm ping*.log', '\$', 5) + SSH.close() + + def LogCollectIperf(self,EPC): + SSH = sshconnection.SSHConnection() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) + SSH.command('cd scripts', '\$', 5) + SSH.command('rm -f iperf.log.zip', '\$', 5) + SSH.command('zip iperf.log.zip iperf*.log', '\$', 60) + SSH.command('rm iperf*.log', '\$', 5) + SSH.close() + + def LogCollectOAIUE(self): + SSH = sshconnection.SSHConnection() + SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + SSH.command('cd ' + self.UESourceCodePath, '\$', 5) + SSH.command('cd cmake_targets', '\$', 5) + SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5) + SSH.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60) + SSH.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5) + SSH.close() + + def RetrieveSystemVersion(self, machine,HTML,RAN): + if RAN.eNBIPAddress == 'none' or self.UEIPAddress == 'none': + HTML.OsVersion[0]='Ubuntu 16.04.5 LTS' + HTML.KernelVersion[0]='4.15.0-45-generic' + HTML.UhdVersion[0]='3.13.0.1-0' + HTML.UsrpBoard[0]='B210' + HTML.CpuNb[0]='4' + HTML.CpuModel[0]='Intel(R) Core(TM) i5-6200U' + HTML.CpuMHz[0]='2399.996 MHz' + return 0 + if machine == 'eNB': + if RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != '': + IPAddress = RAN.eNBIPAddress + UserName = RAN.eNBUserName + Password = RAN.eNBPassword + idx = 0 + else: + return -1 + if machine == 'UE': + if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': + IPAddress = self.UEIPAddress + UserName = self.UEUserName + Password = self.UEPassword + idx = 1 + else: + return -1 + + SSH = sshconnection.SSHConnection() + SSH.open(IPAddress, UserName, Password) + SSH.command('lsb_release -a', '\$', 5) + result = re.search('Description:\\\\t(?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) + if result is not None: + OsVersion = result.group('os_type') + logging.debug('OS is: ' + OsVersion) + HTML.OsVersion[idx]=OsVersion + else: + SSH.command('hostnamectl', '\$', 5) + result = re.search('Operating System: (?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) + if result is not None: + OsVersion = result.group('os_type') + if OsVersion == 'CentOS Linux 7 ': + SSH.command('cat /etc/redhat-release', '\$', 5) + result = re.search('CentOS Linux release (?P[0-9\.]+)', SSH.getBefore()) + if result is not None: + OsVersion = OsVersion.replace('7 ', result.group('os_version')) + logging.debug('OS is: ' + OsVersion) + HTML.OsVersion[idx]=OsVersion + SSH.command('uname -r', '\$', 5) + result = re.search('uname -r\\\\r\\\\n(?P[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) + if result is not None: + KernelVersion = result.group('kernel_version') + logging.debug('Kernel Version is: ' + KernelVersion) + HTML.KernelVersion[idx]=KernelVersion + SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) + result = re.search('libuhd003:amd64 *(?P[0-9\.]+)', SSH.getBefore()) + if result is not None: + UhdVersion = result.group('uhd_version') + logging.debug('UHD Version is: ' + UhdVersion) + HTML.UhdVersion[idx]=UhdVersion + else: + SSH.command('uhd_config_info --version', '\$', 5) + result = re.search('UHD (?P[a-zA-Z0-9\.\-]+)', SSH.getBefore()) + if result is not None: + UhdVersion = result.group('uhd_version') + logging.debug('UHD Version is: ' + UhdVersion) + HTML.UhdVersion[idx]=UhdVersion + SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60) + usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) + count = 0 + for board in usrp_boards: + if count == 0: + UsrpBoard = board + else: + UsrpBoard += ',' + board + count += 1 + if count > 0: + logging.debug('USRP Board(s) : ' + UsrpBoard) + HTML.UsrpBoard[idx]=UsrpBoard + SSH.command('lscpu', '\$', 5) + result = re.search('CPU\(s\): *(?P[0-9]+).*Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P[0-9\.]+)', SSH.getBefore()) + if result is not None: + CpuNb = result.group('nb_cpus') + logging.debug('nb_cpus: ' + CpuNb) + HTML.CpuNb[idx]=CpuNb + CpuModel = result.group('model') + logging.debug('model: ' + CpuModel) + HTML.CpuModel[idx]=CpuModel + CpuMHz = result.group('cpu_mhz') + ' MHz' + logging.debug('cpu_mhz: ' + CpuMHz) + HTML.CpuMHz[idx]=CpuMHz + SSH.close() + + def ConditionalExit(self): + if self.testUnstable: + if self.testStabilityPointReached or self.testMinStableId == '999999': + sys.exit(0) + sys.exit(1) + + def ShowTestID(self): + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') + logging.debug('\u001B[1m' + self.desc + '\u001B[0m') + logging.debug('\u001B[1m----------------------------------------\u001B[0m') diff --git a/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf index becd484c56..e2c94b14ab 100644 --- a/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf +++ b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf @@ -181,6 +181,7 @@ eNBs = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -214,7 +215,7 @@ log_config = { NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf index 7e4dfc6de6..5b994ed29b 100644 --- a/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf +++ b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf @@ -181,6 +181,7 @@ eNBs = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -214,7 +215,7 @@ log_config = { NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf index b1c4774aba..148c5a9903 100644 --- a/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf +++ b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf @@ -181,6 +181,7 @@ eNBs = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -214,7 +215,7 @@ log_config = { NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf index 7167bffa6d..a3ecffb9be 100644 --- a/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf @@ -112,7 +112,7 @@ log_config = { NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf index 3c951a2a6e..1920992d70 100644 --- a/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf @@ -112,7 +112,7 @@ log_config = { NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf index 4726269312..5df8da05a3 100644 --- a/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf @@ -112,7 +112,7 @@ log_config = { NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf index 49926c3e60..e70ca78205 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf @@ -175,6 +175,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -238,7 +239,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "eth0"; - FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; 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 673c506dfa..400d1a6c9d 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -356,6 +356,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -447,7 +448,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf index cf508a1e95..bd2999b5d5 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf @@ -177,6 +177,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -250,7 +251,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "eth0"; - FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf index d26ab5d1b4..19ef6d0797 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf @@ -178,6 +178,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -394,7 +395,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "eth0"; - FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 55127e1c53..f34878c569 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -227,7 +228,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 88e4c88685..e2e482a7c7 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -227,7 +228,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 5794310fad..bfea139e92 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -227,7 +228,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf index 5348c25c0e..4e0025770b 100644 --- a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -225,7 +226,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 7ea8839b8a..1627d21e1a 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -173,6 +173,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -246,7 +247,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf index 36f0fdf7b1..efa1fa64b8 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -255,7 +256,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "eth0"; - FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index b61201440b..f29fc163b3 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -28,83 +28,85 @@ eNBs = node_function = "3GPP_eNODEB"; node_timing = "synch_to_ext_device"; node_synch_ref = 0; - frame_type = "FDD"; - tdd_config = 3; - tdd_config_s = 0; - prefix_type = "NORMAL"; - eutra_band = 7; - downlink_frequency = 2680000000L; - uplink_frequency_offset = -120000000; - Nid_cell = 0; - N_RB_DL = 25; - Nid_cell_mbsfn = 0; - nb_antenna_ports = 1; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 90; - rx_gain = 125; - pbch_repetition = "FALSE"; - prach_root = 0; - prach_config_index = 0; - prach_high_speed = "DISABLE"; - prach_zero_correlation = 1; - prach_freq_offset = 2; - pucch_delta_shift = 1; - pucch_nRB_CQI = 0; - pucch_nCS_AN = 0; - pucch_n1_AN = 0; - pdsch_referenceSignalPower = -25; - pdsch_p_b = 0; - pusch_n_SB = 1; - pusch_enable64QAM = "DISABLE"; - pusch_hoppingMode = "interSubFrame"; - pusch_hoppingOffset = 0; - pusch_groupHoppingEnabled = "ENABLE"; - pusch_groupAssignment = 0; - pusch_sequenceHoppingEnabled = "DISABLE"; - pusch_nDMRS1 = 1; - phich_duration = "NORMAL"; - phich_resource = "ONESIXTH"; - srs_enable = "DISABLE"; - /* srs_BandwidthConfig =; - srs_SubframeConfig =; - srs_ackNackST =; - srs_MaxUpPts =;*/ - - pusch_p0_Nominal = -96; - pusch_alpha = "AL1"; - pucch_p0_Nominal = -104; - msg3_delta_Preamble = 6; - pucch_deltaF_Format1 = "deltaF2"; - pucch_deltaF_Format1b = "deltaF3"; - pucch_deltaF_Format2 = "deltaF0"; - pucch_deltaF_Format2a = "deltaF0"; - pucch_deltaF_Format2b = "deltaF0"; - - rach_numberOfRA_Preambles = 64; - rach_preamblesGroupAConfig = "DISABLE"; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower= -25; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; /* - rach_sizeOfRA_PreamblesGroupA = ; - rach_messageSizeGroupA = ; - rach_messagePowerOffsetGroupB = ; + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; */ - rach_powerRampingStep = 4; - rach_preambleInitialReceivedTargetPower = -108; - rach_preambleTransMax = 10; - rach_raResponseWindowSize = 10; - rach_macContentionResolutionTimer = 48; - rach_maxHARQ_Msg3Tx = 4; - pcch_default_PagingCycle = 128; - pcch_nB = "oneT"; - bcch_modificationPeriodCoeff = 2; - ue_TimersAndConstants_t300 = 1000; - ue_TimersAndConstants_t301 = 1000; - ue_TimersAndConstants_t310 = 1000; - ue_TimersAndConstants_t311 = 10000; - ue_TimersAndConstants_n310 = 20; - ue_TimersAndConstants_n311 = 1; - ue_TransmissionMode = 1; + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; //Parameters for SIB18 rxPool_sc_CP_Len = "normal"; @@ -116,27 +118,28 @@ eNBs = rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; rxPool_ResourceConfig_offsetIndicator_choice = 0; rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; - rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; - rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; - rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; -/* rxPool_dataHoppingConfig_hoppingParameter = 0; - rxPool_dataHoppingConfig_numSubbands = "ns1"; - rxPool_dataHoppingConfig_rbOffset = 0; - rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; */ // Parameters for SIB19 - discRxPool_cp_Len = "normal" - discRxPool_discPeriod = "rf32" - discRxPool_numRetx = 1; - discRxPool_numRepetition = 2; - discRxPool_ResourceConfig_prb_Num = 5; - discRxPool_ResourceConfig_prb_Start = 3; - discRxPool_ResourceConfig_prb_End = 21; - discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; - discRxPool_ResourceConfig_offsetIndicator_choice = 0; - discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; - discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; - discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size= 5; discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; } @@ -176,6 +179,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -203,40 +207,43 @@ eNBs = } ); -MACRLCs = ( - { - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - phy_test_mode = 0; - puSch10xSnr = 160; - puCch10xSnr = 160; - } +MACRLCs = +( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } ); -L1s = ( - { - num_cc = 1; - tr_n_preference = "local_mac"; - } +L1s = +( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } ); -RUs = ( - { - local_rf = "yes" - nb_tx = 1 - nb_rx = 1 - att_tx = 0 - att_rx = 0; - bands = [7]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 125; - eNB_instances = [0]; - - } +RUs = +( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + } ); -THREAD_STRUCT = ( +THREAD_STRUCT = +( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" parallel_config = "PARALLEL_SINGLE_THREAD"; @@ -249,27 +256,27 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "eth0"; - FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; }; - log_config : - { - global_log_level ="info"; - global_log_verbosity ="medium"; - hw_log_level ="info"; - hw_log_verbosity ="medium"; - phy_log_level ="info"; - phy_log_verbosity ="medium"; - mac_log_level ="info"; - mac_log_verbosity ="high"; - rlc_log_level ="info"; - rlc_log_verbosity ="medium"; - pdcp_log_level ="info"; - pdcp_log_verbosity ="medium"; - rrc_log_level ="info"; - rrc_log_verbosity ="medium"; - }; +log_config : +{ + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; +}; diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 8a2cedfd05..4d89ad96da 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -181,6 +181,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -254,7 +255,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf old mode 100755 new mode 100644 index b2d5801efc..33aae14dac --- a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf @@ -183,6 +183,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -265,7 +266,7 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 118; eNB_instances = [0]; - clock_src = "external"; +# clock_src = "external"; } ); diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf index 08dd300329..72754165d0 100644 --- a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -248,7 +249,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf index 371a6b4610..da65aad775 100644 --- a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf @@ -175,6 +175,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -243,7 +244,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "eth0"; - FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index aa03e91fd0..aeba400cad 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -45,8 +45,8 @@ gNBs = dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 13475; + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -74,7 +74,7 @@ gNBs = initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 + #this is SS=1,L=5 initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon @@ -89,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 13475; + initialULBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -126,17 +126,17 @@ gNBs = # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # msg1_SubcarrierSpacing = 1, - # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) initialULBWPk2_0 = 6; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; @@ -145,7 +145,7 @@ gNBs = initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; - + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -204,6 +204,7 @@ gNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "192.168.12.26"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -249,7 +250,7 @@ RUs = ( eNB_instances = [0]; #beamforming 1x4 matrix: bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; - sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf old mode 100755 new mode 100644 index 7a4b5f54c1..258618e7f0 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -2,6 +2,7 @@ Active_gNBs = ( "gNB-Eurecom-5GNRBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; + gNBs = ( { @@ -21,7 +22,10 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; - + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + + servingCellConfigCommon = ( { #spCellConfigCommon @@ -201,6 +205,7 @@ gNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -245,6 +250,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); @@ -259,7 +265,7 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - clock_src = "external"; +# clock_src = "external"; } ); @@ -291,3 +297,6 @@ THREAD_STRUCT = ( rrc_log_verbosity ="medium"; }; +uicc: { +opc = "testopc"; +}; diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 163047d7b9..a4d8e007dc 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -173,6 +173,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf index bb49d68bb4..458ab7cf89 100644 --- a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf @@ -174,6 +174,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf index 2e211d86b8..e80ff2b9cb 100644 --- a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf @@ -174,6 +174,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index ad7e9d9f86..f443a907f2 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -136,6 +136,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf b/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf index b3899fdb6a..502e3c548a 100644 --- a/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf +++ b/ci-scripts/conf_files/rcc.band38.tm1.50PRB.multi.rru.conf @@ -141,6 +141,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 0547590c29..d01e4e1c4e 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -139,6 +139,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -234,7 +235,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 3441690e6d..419598647b 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -139,6 +139,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -234,7 +235,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 23709444bd..d4f2eb9ef2 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -139,6 +139,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -234,7 +235,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index 33d00b8908..683fff0bc8 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -253,7 +254,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index a939c66cba..2c3c11b84f 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -253,7 +254,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index 473496defa..49365a1f61 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -176,6 +176,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } @@ -253,7 +254,7 @@ NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf index bf2db71152..640b85930a 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf @@ -144,6 +144,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "192.168.15.130"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf index 3bcd038d70..7fe682f29e 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf @@ -144,6 +144,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "127.0.0.3"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf index ad113d0ffc..281f7433af 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -174,6 +174,7 @@ eNBs = ////////// MME parameters: mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; + port = 36412 ; active = "yes"; preference = "ipv4"; } diff --git a/ci-scripts/conf_files/rru.fdd.band7.conf b/ci-scripts/conf_files/rru.fdd.band7.conf index ea923ae371..057f518046 100644 --- a/ci-scripts/conf_files/rru.fdd.band7.conf +++ b/ci-scripts/conf_files/rru.fdd.band7.conf @@ -1,23 +1,25 @@ -RUs = ( - { - local_if_name = "lo"; - remote_address = "127.0.0.1" - local_address = "127.0.0.2"; - local_portc = 50000; - remote_portc = 50000; - local_portd = 50001; - remote_portd = 50001; - local_rf = "yes" - tr_preference = "udp_if4p5"; - nb_tx = 1; - nb_rx = 1; - max_pdschReferenceSignalPower = -27; - max_rxgain = 115; - bands = [7]; - } +RUs = +( + { + local_if_name = "lo"; + remote_address = "127.0.0.1" + local_address = "127.0.0.2"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "yes" + tr_preference = "udp_if4p5"; + nb_tx = 1; + nb_rx = 1; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + bands = [7]; + } ); -THREAD_STRUCT = ( +THREAD_STRUCT = +( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" parallel_config = "PARALLEL_SINGLE_THREAD"; @@ -26,19 +28,20 @@ THREAD_STRUCT = ( } ); -log_config = { - global_log_level ="error"; - global_log_verbosity ="medium"; - hw_log_level ="error"; - hw_log_verbosity ="medium"; - phy_log_level ="error"; - phy_log_verbosity ="medium"; - mac_log_level ="error"; - mac_log_verbosity ="high"; - rlc_log_level ="error"; - rlc_log_verbosity ="medium"; - pdcp_log_level ="error"; - pdcp_log_verbosity ="medium"; - rrc_log_level ="error"; - rrc_log_verbosity ="medium"; +log_config = +{ + global_log_level ="error"; + global_log_verbosity ="medium"; + hw_log_level ="error"; + hw_log_verbosity ="medium"; + phy_log_level ="error"; + phy_log_verbosity ="medium"; + mac_log_level ="error"; + mac_log_verbosity ="high"; + rlc_log_level ="error"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="error"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="error"; + rrc_log_verbosity ="medium"; }; diff --git a/ci-scripts/conf_files/rru.tdd.band40.conf b/ci-scripts/conf_files/rru.tdd.band40.conf index 904f8c9598..5ce3a515f5 100644 --- a/ci-scripts/conf_files/rru.tdd.band40.conf +++ b/ci-scripts/conf_files/rru.tdd.band40.conf @@ -1,23 +1,25 @@ -RUs = ( - { - local_if_name = "lo"; - remote_address = "127.0.0.1" - local_address = "127.0.0.2"; - local_portc = 50000; - remote_portc = 50000; - local_portd = 50001; - remote_portd = 50001; - local_rf = "yes" - tr_preference = "udp_if4p5"; - nb_tx = 1; - nb_rx = 1; - max_pdschReferenceSignalPower = -27; - max_rxgain = 115; - bands = [40]; - } +RUs = +( + { + local_if_name = "lo"; + remote_address = "127.0.0.1" + local_address = "127.0.0.2"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "yes" + tr_preference = "udp_if4p5"; + nb_tx = 1; + nb_rx = 1; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + bands = [40]; + } ); -THREAD_STRUCT = ( +THREAD_STRUCT = +( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" parallel_config = "PARALLEL_SINGLE_THREAD"; @@ -26,19 +28,20 @@ THREAD_STRUCT = ( } ); -log_config = { - global_log_level ="error"; - global_log_verbosity ="medium"; - hw_log_level ="error"; - hw_log_verbosity ="medium"; - phy_log_level ="error"; - phy_log_verbosity ="medium"; - mac_log_level ="error"; - mac_log_verbosity ="high"; - rlc_log_level ="error"; - rlc_log_verbosity ="medium"; - pdcp_log_level ="error"; - pdcp_log_verbosity ="medium"; - rrc_log_level ="error"; - rrc_log_verbosity ="medium"; +log_config = +{ + global_log_level ="error"; + global_log_verbosity ="medium"; + hw_log_level ="error"; + hw_log_verbosity ="medium"; + phy_log_level ="error"; + phy_log_verbosity ="medium"; + mac_log_level ="error"; + mac_log_verbosity ="high"; + rlc_log_level ="error"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="error"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="error"; + rrc_log_verbosity ="medium"; }; diff --git a/ci-scripts/constants.py b/ci-scripts/constants.py index c5698c5a3e..a0e1ac5c45 100644 --- a/ci-scripts/constants.py +++ b/ci-scripts/constants.py @@ -59,6 +59,7 @@ OAI_UE_PROCESS_NO_TUNNEL_INTERFACE = -24 OAI_UE_PROCESS_SEG_FAULT = -25 OAI_UE_PROCESS_NO_MBMS_MSGS = -26 OAI_UE_PROCESS_OK = +6 +INVALID_PARAMETER = -50 UE_STATUS_DETACHED = 0 UE_STATUS_DETACHING = 1 diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list index 4b9fb97427..f8438a4276 100644 --- a/ci-scripts/cppcheck_suppressions.list +++ b/ci-scripts/cppcheck_suppressions.list @@ -84,6 +84,12 @@ nullPointer:common/utils/T/tracer/multi.c:265 arrayIndexOutOfBounds:openair2/LAYER2/rlc_v2/tests/test.c:401 // //----------------------------------------------------------------------------- +// this file is used for testing the NR RLC implementation, this error is +// not a problem, the programmer has to know what she does when writing +// the tests +arrayIndexOutOfBounds:openair2/LAYER2/nr_rlc/tests/test.c:451 +// +//----------------------------------------------------------------------------- // cppcheck does not understand the different lengths of arrays arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:705 arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:706 diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 25bbbba091..cd5a747654 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -46,7 +46,6 @@ from multiprocessing import Process, Lock, SimpleQueue import sshconnection as SSH import helpreadme as HELP import constants as CONST -import html #----------------------------------------------------------- # Class Declaration @@ -61,17 +60,18 @@ class EPCManagement(): self.SourceCodePath = '' self.Type = '' self.PcapFileName = '' - self.htmlObj = None self.testCase_id = '' self.MmeIPAddress = '' self.containerPrefix = 'prod' + self.mmeConfFile = 'mme.conf' + self.yamlPath = '' #----------------------------------------------------------- # EPC management functions #----------------------------------------------------------- - def InitializeHSS(self): + def InitializeHSS(self, HTML): if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '': HELP.GenericHelp(CONST.Version) HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type) @@ -113,10 +113,9 @@ class EPCManagement(): else: logging.error('This option should not occur!') mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) - def InitializeMME(self): + def InitializeMME(self, HTML): if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '': HELP.GenericHelp(CONST.Version) HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type) @@ -127,7 +126,7 @@ class EPCManagement(): logging.debug('Using the OAI EPC Release 14 MME in Docker') mySSH.command('docker exec -d ' + self.containerPrefix + '-oai-mme /bin/bash -c "nohup tshark -i eth0 -i lo:s10 -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 5) time.sleep(5) - mySSH.command('docker exec -d ' + self.containerPrefix + '-oai-mme /bin/bash -c "nohup ./bin/oai_mme -c ./etc/mme.conf > mme_check_run.log 2>&1"', '\$', 5) + mySSH.command('docker exec -d ' + self.containerPrefix + '-oai-mme /bin/bash -c "nohup ./bin/oai_mme -c ./etc/' + self.mmeConfFile + ' > mme_check_run.log 2>&1"', '\$', 5) elif re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE): logging.debug('Using the OAI EPC Release 14 MME') mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) @@ -152,8 +151,7 @@ class EPCManagement(): else: logging.error('This option should not occur!') mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) def SetMmeIPAddress(self): # Not an error if we don't need an EPC @@ -174,7 +172,7 @@ class EPCManagement(): else: self.MmeIPAddress = self.IPAddress - def InitializeSPGW(self): + def InitializeSPGW(self, HTML): if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '': HELP.GenericHelp(CONST.Version) HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type) @@ -211,15 +209,14 @@ class EPCManagement(): else: logging.error('This option should not occur!') mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) def CheckHSSProcess(self, status_queue): try: mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-hss /bin/bash -c "ps aux | grep oai_hss"', '\$', 5) + mySSH.command('docker top ' + self.containerPrefix + '-oai-hss', '\$', 5) else: mySSH.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5) if re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): @@ -244,7 +241,7 @@ class EPCManagement(): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-mme /bin/bash -c "ps aux | grep oai_mme"', '\$', 5) + mySSH.command('docker top ' + self.containerPrefix + '-oai-mme', '\$', 5) else: mySSH.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): @@ -271,11 +268,11 @@ class EPCManagement(): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-spgwc /bin/bash -c "ps aux | grep oai_spgwc"', '\$', 5) - result = re.search('oai_spgwc -o -c ', mySSH.getBefore()) + mySSH.command('docker top ' + self.containerPrefix + '-oai-spgwc', '\$', 5) + result = re.search('oai_spgwc -', mySSH.getBefore()) if result is not None: - mySSH.command('docker exec -it ' + self.containerPrefix + '-oai-spgwu-tiny /bin/bash -c "ps aux | grep oai_spgwu"', '\$', 5) - result = re.search('oai_spgwu -o -c ', mySSH.getBefore()) + mySSH.command('docker top ' + self.containerPrefix + '-oai-spgwu-tiny', '\$', 5) + result = re.search('oai_spgwu -', mySSH.getBefore()) elif re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE): mySSH.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) result = re.search('spgwu -c ', mySSH.getBefore()) @@ -296,7 +293,7 @@ class EPCManagement(): except: os.kill(os.getppid(),signal.SIGUSR1) - def TerminateHSS(self): + def TerminateHSS(self, HTML): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): @@ -329,10 +326,9 @@ class EPCManagement(): else: logging.error('This should not happen!') mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - def TerminateMME(self): + def TerminateMME(self, HTML): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): @@ -356,10 +352,9 @@ class EPCManagement(): else: logging.error('This should not happen!') mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - def TerminateSPGW(self): + def TerminateSPGW(self, HTML): mySSH = SSH.SSHConnection() mySSH.open(self.IPAddress, self.UserName, self.Password) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): @@ -400,8 +395,155 @@ class EPCManagement(): else: logging.error('This should not happen!') mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) + + def DeployEpc(self, HTML): + logging.debug('Trying to deploy') + if not re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): + HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) + HTML.CreateHtmlTabFooter(False) + sys.exit('Deploy not possible with this EPC type: ' + self.Type) + + if self.IPAddress == '' or self.UserName == '' or self.Password == '' or self.SourceCodePath == '' or self.Type == '': + HELP.GenericHelp(CONST.Version) + HELP.EPCSrvHelp(self.IPAddress, self.UserName, self.Password, self.SourceCodePath, self.Type) + sys.exit('Insufficient EPC Parameters') + mySSH = SSH.SSHConnection() + mySSH.open(self.IPAddress, self.UserName, self.Password) + mySSH.command('docker-compose --version', '\$', 5) + result = re.search('docker-compose version 1', mySSH.getBefore()) + if result is None: + mySSH.close() + HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) + HTML.CreateHtmlTabFooter(False) + sys.exit('docker-compose not installed on ' + self.IPAddress) + + mySSH.command('if [ -d ' + self.SourceCodePath + '/scripts ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/scripts ; fi', '\$', 5) + mySSH.command('if [ -d ' + self.SourceCodePath + '/logs ]; then echo ' + self.Password + ' | sudo -S rm -Rf ' + self.SourceCodePath + '/logs ; fi', '\$', 5) + mySSH.command('mkdir -p ' + self.SourceCodePath + '/scripts ' + self.SourceCodePath + '/logs', '\$', 5) + + # deploying and configuring the cassandra database + # container names and services are currently hard-coded. + # they could be recovered by: + # - docker-compose config --services + # - docker-compose config | grep container_name + mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) + mySSH.copyout(self.IPAddress, self.UserName, self.Password, './' + self.yamlPath + '/docker-compose.yml', self.SourceCodePath + '/scripts') + mySSH.command('wget --quiet --tries=3 --retry-connrefused https://raw.githubusercontent.com/OPENAIRINTERFACE/openair-hss/develop/src/hss_rel14/db/oai_db.cql', '\$', 30) + mySSH.command('docker-compose down', '\$', 60) + mySSH.command('docker-compose up -d db_init', '\$', 60) + + # databases take time... + time.sleep(10) + cnt = 0 + db_init_status = False + while (cnt < 10): + mySSH.command('docker logs prod-db-init', '\$', 5) + result = re.search('OK', mySSH.getBefore()) + if result is not None: + cnt = 10 + db_init_status = True + else: + time.sleep(5) + cnt += 1 + mySSH.command('docker rm -f prod-db-init', '\$', 5) + if not db_init_status: + HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) + HTML.CreateHtmlTabFooter(False) + sys.exit('Cassandra DB deployment/configuration went wrong!') + + # deploying EPC cNFs + mySSH.command('docker-compose up -d oai_spgwu', '\$', 60) + listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny' + expectedHealthyContainers = 5 + + # Checking for additional services + mySSH.command('docker-compose config', '\$', 5) + configResponse = mySSH.getBefore() + if configResponse.count('flexran_rtc') == 1: + mySSH.command('docker-compose up -d flexran_rtc', '\$', 60) + listOfContainers += ' prod-flexran-rtc' + expectedHealthyContainers += 1 + if configResponse.count('trf_gen') == 1: + mySSH.command('docker-compose up -d trf_gen', '\$', 60) + listOfContainers += ' prod-trf-gen' + expectedHealthyContainers += 1 + + # Checking if all are healthy + cnt = 0 + while (cnt < 3): + mySSH.command('docker inspect --format=\'{{.State.Health.Status}}\' ' + listOfContainers, '\$', 10) + unhealthyNb = mySSH.getBefore().count('unhealthy') + healthyNb = mySSH.getBefore().count('healthy') - unhealthyNb + startingNb = mySSH.getBefore().count('starting') + if healthyNb == expectedHealthyContainers: + cnt = 10 + else: + time.sleep(10) + cnt += 1 + logging.debug(' -- ' + str(healthyNb) + ' healthy container(s)') + logging.debug(' -- ' + str(unhealthyNb) + ' unhealthy container(s)') + logging.debug(' -- ' + str(startingNb) + ' still starting container(s)') + if healthyNb == expectedHealthyContainers: + mySSH.command('docker exec -d prod-oai-hss /bin/bash -c "nohup tshark -i any -f \'port 9042 or port 3868\' -w /tmp/hss_check_run.pcap 2>&1 > /dev/null"', '\$', 5) + mySSH.command('docker exec -d prod-oai-mme /bin/bash -c "nohup tshark -i any -f \'port 3868 or port 2123 or port 36412\' -w /tmp/mme_check_run.pcap 2>&1 > /dev/null"', '\$', 10) + mySSH.command('docker exec -d prod-oai-spgwc /bin/bash -c "nohup tshark -i any -f \'port 2123 or port 8805\' -w /tmp/spgwc_check_run.pcap 2>&1 > /dev/null"', '\$', 10) + # on SPGW-U, not capturing on SGI to avoid huge file + mySSH.command('docker exec -d prod-oai-spgwu-tiny /bin/bash -c "nohup tshark -i any -f \'port 8805\' -w /tmp/spgwu_check_run.pcap 2>&1 > /dev/null"', '\$', 10) + mySSH.close() + logging.debug('Deployment OK') + HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) + else: + mySSH.close() + logging.debug('Deployment went wrong') + HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) + + def UndeployEpc(self, HTML): + logging.debug('Trying to undeploy') + # No check down, we suppose everything done before. + + mySSH = SSH.SSHConnection() + mySSH.open(self.IPAddress, self.UserName, self.Password) + # Recovering logs and pcap files + mySSH.command('cd ' + self.SourceCodePath + '/logs', '\$', 5) + mySSH.command('docker exec -it prod-oai-hss /bin/bash -c "killall --signal SIGINT oai_hss tshark"', '\$', 5) + mySSH.command('docker exec -it prod-oai-mme /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5) + mySSH.command('docker exec -it prod-oai-spgwc /bin/bash -c "killall --signal SIGINT oai_spgwc tshark"', '\$', 5) + mySSH.command('docker exec -it prod-oai-spgwu-tiny /bin/bash -c "killall --signal SIGINT tshark"', '\$', 5) + mySSH.command('docker logs prod-oai-hss > hss_' + self.testCase_id + '.log', '\$', 5) + mySSH.command('docker logs prod-oai-mme > mme_' + self.testCase_id + '.log', '\$', 5) + mySSH.command('docker logs prod-oai-spgwc > spgwc_' + self.testCase_id + '.log', '\$', 5) + mySSH.command('docker logs prod-oai-spgwu-tiny > spgwu_' + self.testCase_id + '.log', '\$', 5) + mySSH.command('docker cp prod-oai-hss:/tmp/hss_check_run.pcap hss_' + self.testCase_id + '.pcap', '\$', 60) + mySSH.command('docker cp prod-oai-mme:/tmp/mme_check_run.pcap mme_' + self.testCase_id + '.pcap', '\$', 60) + mySSH.command('docker cp prod-oai-spgwc:/tmp/spgwc_check_run.pcap spgwc_' + self.testCase_id + '.pcap', '\$', 60) + mySSH.command('docker cp prod-oai-spgwu-tiny:/tmp/spgwu_check_run.pcap spgwu_' + self.testCase_id + '.pcap', '\$', 60) + # Remove all + mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) + listOfContainers = 'prod-cassandra prod-oai-hss prod-oai-mme prod-oai-spgwc prod-oai-spgwu-tiny' + nbContainers = 5 + # Checking for additional services + mySSH.command('docker-compose config', '\$', 5) + configResponse = mySSH.getBefore() + if configResponse.count('flexran_rtc') == 1: + listOfContainers += ' prod-flexran-rtc' + nbContainers += 1 + if configResponse.count('trf_gen') == 1: + listOfContainers += ' prod-trf-gen' + nbContainers += 1 + + mySSH.command('docker-compose down', '\$', 60) + mySSH.command('docker inspect --format=\'{{.State.Health.Status}}\' ' + listOfContainers, '\$', 10) + noMoreContainerNb = mySSH.getBefore().count('No such object') + mySSH.command('docker inspect --format=\'{{.Name}}\' prod-oai-public-net prod-oai-private-net', '\$', 10) + noMoreNetworkNb = mySSH.getBefore().count('No such object') + mySSH.close() + if noMoreContainerNb == nbContainers and noMoreNetworkNb == 2: + logging.debug('Undeployment OK') + HTML.CreateHtmlTestRow(self.Type, 'OK', CONST.ALL_PROCESSES_OK) + else: + logging.debug('Undeployment went wrong') + HTML.CreateHtmlTestRow(self.Type, 'KO', CONST.INVALID_PARAMETER) def LogCollectHSS(self): mySSH = SSH.SSHConnection() @@ -409,9 +551,17 @@ class EPCManagement(): mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) mySSH.command('rm -f hss.log.zip', '\$', 5) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker cp ' + self.containerPrefix + '-oai-hss:/openair-hss/hss_check_run.log .', '\$', 60) - mySSH.command('docker cp ' + self.containerPrefix + '-oai-hss:/tmp/hss_check_run.pcap .', '\$', 60) - mySSH.command('zip hss.log.zip hss_check_run.*', '\$', 60) + mySSH.command('docker inspect prod-oai-hss', '\$', 10) + result = re.search('No such object', mySSH.getBefore()) + if result is not None: + mySSH.command('cd ../logs', '\$', 5) + mySSH.command('rm -f hss.log.zip', '\$', 5) + mySSH.command('zip hss.log.zip hss_*.*', '\$', 60) + mySSH.command('mv hss.log.zip ../scripts', '\$', 60) + else: + mySSH.command('docker cp ' + self.containerPrefix + '-oai-hss:/openair-hss/hss_check_run.log .', '\$', 60) + mySSH.command('docker cp ' + self.containerPrefix + '-oai-hss:/tmp/hss_check_run.pcap .', '\$', 60) + mySSH.command('zip hss.log.zip hss_check_run.*', '\$', 60) elif re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE): mySSH.command('zip hss.log.zip hss*.log', '\$', 60) mySSH.command('echo ' + self.Password + ' | sudo -S rm hss*.log', '\$', 5) @@ -431,9 +581,17 @@ class EPCManagement(): mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) mySSH.command('rm -f mme.log.zip', '\$', 5) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker cp ' + self.containerPrefix + '-oai-mme:/openair-mme/mme_check_run.log .', '\$', 60) - mySSH.command('docker cp ' + self.containerPrefix + '-oai-mme:/tmp/mme_check_run.pcap .', '\$', 60) - mySSH.command('zip mme.log.zip mme_check_run.*', '\$', 60) + mySSH.command('docker inspect prod-oai-mme', '\$', 10) + result = re.search('No such object', mySSH.getBefore()) + if result is not None: + mySSH.command('cd ../logs', '\$', 5) + mySSH.command('rm -f mme.log.zip', '\$', 5) + mySSH.command('zip mme.log.zip mme_*.*', '\$', 60) + mySSH.command('mv mme.log.zip ../scripts', '\$', 60) + else: + mySSH.command('docker cp ' + self.containerPrefix + '-oai-mme:/openair-mme/mme_check_run.log .', '\$', 60) + mySSH.command('docker cp ' + self.containerPrefix + '-oai-mme:/tmp/mme_check_run.pcap .', '\$', 60) + mySSH.command('zip mme.log.zip mme_check_run.*', '\$', 60) elif re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE): mySSH.command('zip mme.log.zip mme*.log', '\$', 60) mySSH.command('echo ' + self.Password + ' | sudo -S rm mme*.log', '\$', 5) @@ -450,11 +608,19 @@ class EPCManagement(): mySSH.command('cd ' + self.SourceCodePath + '/scripts', '\$', 5) mySSH.command('rm -f spgw.log.zip', '\$', 5) if re.match('OAI-Rel14-Docker', self.Type, re.IGNORECASE): - mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwc:/openair-spgwc/spgwc_check_run.log .', '\$', 60) - mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwu-tiny:/openair-spgwu-tiny/spgwu_check_run.log .', '\$', 60) - mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwc:/tmp/spgwc_check_run.pcap .', '\$', 60) - mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwu-tiny:/tmp/spgwu_check_run.pcap .', '\$', 60) - mySSH.command('zip spgw.log.zip spgw*_check_run.*', '\$', 60) + mySSH.command('docker inspect prod-oai-mme', '\$', 10) + result = re.search('No such object', mySSH.getBefore()) + if result is not None: + mySSH.command('cd ../logs', '\$', 5) + mySSH.command('rm -f spgw.log.zip', '\$', 5) + mySSH.command('zip spgw.log.zip spgw*.*', '\$', 60) + mySSH.command('mv spgw.log.zip ../scripts', '\$', 60) + else: + mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwc:/openair-spgwc/spgwc_check_run.log .', '\$', 60) + mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwu-tiny:/openair-spgwu-tiny/spgwu_check_run.log .', '\$', 60) + mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwc:/tmp/spgwc_check_run.pcap .', '\$', 60) + mySSH.command('docker cp ' + self.containerPrefix + '-oai-spgwu-tiny:/tmp/spgwu_check_run.pcap .', '\$', 60) + mySSH.command('zip spgw.log.zip spgw*_check_run.*', '\$', 60) elif re.match('OAI', self.Type, re.IGNORECASE) or re.match('OAI-Rel14-CUPS', self.Type, re.IGNORECASE): mySSH.command('zip spgw.log.zip spgw*.log', '\$', 60) mySSH.command('echo ' + self.Password + ' | sudo -S rm spgw*.log', '\$', 5) diff --git a/ci-scripts/html.py b/ci-scripts/html.py index 8f2d38cced..b3ee00e7dc 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -64,6 +64,10 @@ class HTMLManagement(): self.htmlTabIcons = [] self.testXMLfiles = [] + self.testUnstable = False + self.testMinStableId = '999999' + self.testStabilityPointReached = False + self.htmleNBFailureMsg = '' self.htmlUEFailureMsg = '' @@ -214,7 +218,7 @@ class HTMLManagement(): self.htmlFile.write('
\n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -230,13 +234,20 @@ class HTMLManagement(): def CreateHtmlTabFooter(self, passStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): + testOkEvenIfUnstable = False + if self.testUnstable and not passStatus: + if self.testStabilityPointReached or self.testMinStableId == '999999': + testOkEvenIfUnstable = True self.htmlFile = open('test_results.html', 'a') self.htmlFile.write(' \n') self.htmlFile.write(' \n') if passStatus: self.htmlFile.write(' \n') else: - self.htmlFile.write(' \n') + if testOkEvenIfUnstable: + self.htmlFile.write(' \n') + else: + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write('
Relative Time (ms)Relative Time (s)Test IdTest DescTest Options
Final Tab StatusPASS FAIL KNOWN UNSTABLE SCENARIO FAIL
\n') self.htmlFile.write('
\n') @@ -246,7 +257,10 @@ class HTMLManagement(): cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__//' test_results.html" subprocess.run(cmd, shell=True) else: - cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" + if testOkEvenIfUnstable: + cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" + else: + cmd = "sed -i -e 's/__STATE_" + self.htmlTabNames[0] + "__/<\/span>/' test_results.html" subprocess.run(cmd, shell=True) self.htmlFooterCreated = False @@ -385,6 +399,53 @@ class HTMLManagement(): self.htmlFile.write(' \n') self.htmlFile.close() + + def CreateHtmlNextTabHeaderTestRow(self, collectInfo, allImagesSize, machine='eNB'): + if (self.htmlFooterCreated or (not self.htmlHeaderCreated)): + return + self.htmlFile = open('test_results.html', 'a') + if bool(collectInfo) == False: + self.htmlFile.write(' \n') + self.htmlFile.write(' ----IMAGES BUILDING FAILED - Unable to recover the image logs ---- \n') + self.htmlFile.write(' \n') + else: + for image in collectInfo: + files = collectInfo[image] + # TabHeader for image logs on built shared and target images + self.htmlFile.write(' \n') + self.htmlFile.write(' ---- ' + image + ' IMAGE STATUS ----> Size ' + allImagesSize[image] + ' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' Element\n') + self.htmlFile.write(' Nb Errors\n') + self.htmlFile.write(' Nb Warnings\n') + self.htmlFile.write(' Status\n') + self.htmlFile.write(' \n') + + for fil in files: + parameters = files[fil] + # TestRow for image logs on built shared and target images + self.htmlFile.write(' \n') + self.htmlFile.write(' ' + fil + ' \n') + if (parameters['errors'] == 0): + self.htmlFile.write(' ' + str(parameters['errors']) + '\n') + else: + self.htmlFile.write(' ' + str(parameters['errors']) + '\n') + if (parameters['warnings'] == 0): + self.htmlFile.write(' ' + str(parameters['warnings']) + '\n') + elif ((parameters['warnings'] > 0) and (parameters['warnings'] <= 20)): + self.htmlFile.write(' ' + str(parameters['warnings']) + '\n') + else: + self.htmlFile.write(' ' + str(parameters['warnings']) + '\n') + if (parameters['errors'] == 0) and (parameters['warnings'] == 0): + self.htmlFile.write(' OK \n') + elif (parameters['errors'] == 0) and ((parameters['warnings'] > 0) and (parameters['warnings'] <= 20)): + self.htmlFile.write(' OK \n') + else: + self.htmlFile.write(' NOT OK \n') + self.htmlFile.write(' \n') + self.htmlFile.close() + def CreateHtmlTestRowQueue(self, options, status, ue_status, ue_queue): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): self.htmlFile = open('test_results.html', 'a') diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 86fd9d84df..3094197c54 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -37,8 +37,12 @@ import helpreadme as HELP import constants as CONST + +import cls_oaicitest #main class for OAI CI test framework import cls_physim #class PhySim for physical simulators build and test import cls_cots_ue #class CotsUe for Airplane mode control +import cls_containerize #class Containerize for all container-based operations on RAN/UE objects + import sshconnection import epc @@ -67,3055 +71,6 @@ logging.basicConfig( -#----------------------------------------------------------- -# OaiCiTest Class Definition -#----------------------------------------------------------- -class OaiCiTest(): - - def __init__(self): - self.ranRepository = '' - self.ranBranch = '' - self.ranCommitID = '' - self.ranAllowMerge = False - self.ranTargetBranch = '' - - self.FailReportCnt = 0 - self.ADBIPAddress = '' - self.ADBUserName = '' - self.ADBPassword = '' - self.ADBCentralized = True - self.testCase_id = '' - self.testXMLfiles = [] - self.desc = '' - self.ping_args = '' - self.ping_packetloss_threshold = '' - self.iperf_args = '' - self.iperf_packetloss_threshold = '' - self.iperf_profile = '' - self.iperf_options = '' - self.nbMaxUEtoAttach = -1 - self.UEDevices = [] - self.UEDevicesStatus = [] - self.UEDevicesRemoteServer = [] - self.UEDevicesRemoteUser = [] - self.UEDevicesOffCmd = [] - self.UEDevicesOnCmd = [] - self.UEDevicesRebootCmd = [] - self.CatMDevices = [] - self.UEIPAddresses = [] - self.idle_sleep_time = 0 - self.x2_ho_options = 'network' - self.x2NbENBs = 0 - self.x2ENBBsIds = [] - self.x2ENBConnectedUEs = [] - self.repeatCounts = [] - self.finalStatus = False - self.UEIPAddress = '' - self.UEUserName = '' - self.UEPassword = '' - self.UE_instance = 0 - self.UESourceCodePath = '' - self.UELogFile = '' - self.Build_OAI_UE_args = '' - self.Initialize_OAI_UE_args = '' - self.clean_repository = True - self.air_interface='' - self.expectedNbOfConnectedUEs = 0 - - def BuildOAIUE(self): - if self.UEIPAddress == '' or self.ranRepository == '' or self.ranBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - result = re.search('--nrUE', self.Build_OAI_UE_args) - if result is not None: - self.air_interface='nr-uesoftmodem' - ue_prefix = 'NR ' - else: - self.air_interface='lte-uesoftmodem' - ue_prefix = '' - 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' - SSH.command('mkdir -p ' + self.UESourceCodePath, '\$', 5) - SSH.command('cd ' + self.UESourceCodePath, '\$', 5) - SSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) - # here add a check if git clone or git fetch went smoothly - SSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - SSH.command('git config user.name "OAI Jenkins"', '\$', 5) - if self.clean_repository: - SSH.command('ls *.txt', '\$', 5) - result = re.search('LAST_BUILD_INFO', SSH.getBefore()) - if result is not None: - mismatch = False - SSH.command('grep SRC_COMMIT LAST_BUILD_INFO.txt', '\$', 2) - result = re.search(self.ranCommitID, SSH.getBefore()) - if result is None: - mismatch = True - SSH.command('grep MERGED_W_TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranAllowMerge: - result = re.search('YES', SSH.getBefore()) - if result is None: - mismatch = True - SSH.command('grep TGT_BRANCH LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - result = re.search('develop', SSH.getBefore()) - else: - result = re.search(self.ranTargetBranch, SSH.getBefore()) - if result is None: - mismatch = True - else: - result = re.search('NO', SSH.getBefore()) - if result is None: - mismatch = True - if not mismatch: - SSH.close() - HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK) - return - - SSH.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 != '': - SSH.command('git checkout -f ' + self.ranCommitID, '\$', 5) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if self.ranAllowMerge: - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - SSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - SSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) - SSH.command('source oaienv', '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('mkdir -p log', '\$', 5) - SSH.command('chmod 777 log', '\$', 5) - # no need to remove in log (git clean did the trick) - SSH.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee compile_oai_ue.log', 'Bypassing the Tests|build have failed', 900) - SSH.command('ls ran_build/build', '\$', 3) - SSH.command('ls ran_build/build', '\$', 3) - buildStatus = True - result = re.search(self.air_interface, SSH.getBefore()) - if result is None: - buildStatus = False - SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) - SSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) - SSH.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5) - if buildStatus: - # Generating a BUILD INFO file - SSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranAllowMerge: - SSH.command('echo "MERGED_W_TGT_BRANCH: YES" >> ../LAST_BUILD_INFO.txt', '\$', 2) - if self.ranTargetBranch == '': - SSH.command('echo "TGT_BRANCH: develop" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - SSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) - else: - SSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) - SSH.close() - HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') - else: - SSH.close() - logging.error('\u001B[1m Building OAI UE Failed\u001B[0m') - HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'KO', CONST.ALL_PROCESSES_OK, 'OAI UE') - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - - def CheckFlexranCtrlInstallation(self): - if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': - return - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) - result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore()) - if result is not None: - RAN.flexranCtrlInstalled=True - logging.debug('Flexran Controller is installed') - SSH.close() - - def InitializeFlexranCtrl(self): - if RAN.flexranCtrlInstalled == False: - return - if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd /opt/flexran_rtc', '\$', 5) - SSH.command('echo ' + EPC.Password + ' | sudo -S rm -f log/*.log', '\$', 5) - SSH.command('echo ' + EPC.Password + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) - SSH.command('echo ' + EPC.Password + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) - SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) - SSH.command('ps -aux | grep --color=never rt_controller', '\$', 5) - result = re.search('rt_controller -c ', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') - RAN.flexranCtrlStarted=True - SSH.close() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def InitializeUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if not self.ADBCentralized: - # Reboot UE - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesRebootCmd[idx], '\$', 60) - # Wait - #time.sleep(60) - # Put in LTE-Mode only - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode 11"\'', '\$', 60) - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode1 11"\'', '\$', 60) - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode2 11"\'', '\$', 60) - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "settings put global preferred_network_mode3 11"\'', '\$', 60) - # enable data service - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # we need to do radio on/off cycle to make sure of above changes - # airplane mode off // radio on - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - #time.sleep(10) - # airplane mode on // radio off - #SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - - # normal procedure without reboot - # enable data service - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - # airplane mode on // radio off - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - SSH.close() - return - - #RH quick add-on to integrate cots control defined by yaml - #if device_id exists in yaml dictionary, we execute the new procedure defined in cots_ue class - #otherwise we use the legacy procedure - if COTS_UE.Check_Exists(device_id): - #switch device to Airplane mode ON (ie Radio OFF) - COTS_UE.Set_Airplane(device_id, 'ON') - else: - # enable data service - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - - # The following commands are deprecated since we no longer work on Android 7+ - # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10) - # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60) - # a dedicated script has to be installed inside the UE - # airplane mode on means call /data/local/tmp/off - if device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - #airplane mode off means call /data/local/tmp/on - logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def InitializeUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.InitializeUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def InitializeOAIUE(self): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - if self.air_interface == 'lte-uesoftmodem': - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - UE_prefix = '' - else: - UE_prefix = 'NR ' - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - # b2xx_fx3_utils reset procedure - SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) - result = re.search('type: b200', SSH.getBefore()) - if result is not None: - logging.debug('Found a B2xx device --> resetting it') - SSH.command('echo ' + self.UEPassword + ' | sudo -S b2xx_fx3_utils --reset-device', '\$', 10) - # Reloading FGPA bin firmware - SSH.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 60) - result = re.search('type: n3xx', str(SSH.getBefore())) - if result is not None: - logging.debug('Found a N3xx device --> resetting it') - SSH.command('cd ' + self.UESourceCodePath, '\$', 5) - # Initialize_OAI_UE_args usually start with -C and followed by the location in repository - SSH.command('source oaienv', '\$', 5) - SSH.command('cd cmake_targets/ran_build/build', '\$', 5) - if self.air_interface == 'lte-uesoftmodem': - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - # We may have to regenerate the .u* files - if result is None: - SSH.command('ls /tmp/*.sed', '\$', 5) - result = re.search('adapt_usim_parameters', SSH.getBefore()) - if result is not None: - SSH.command('sed -f /tmp/adapt_usim_parameters.sed ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - else: - SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) - else: - SSH.command('if [ -e rbconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm rbconfig.raw; fi', '\$', 5) - SSH.command('if [ -e reconfig.raw ]; then echo ' + self.UEPassword + ' | sudo -S rm reconfig.raw; fi', '\$', 5) - # Copy the RAW files from gNB running directory (maybe on another machine) - copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/rbconfig.raw', '.') - if (copyin_res == 0): - SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './rbconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build') - copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/reconfig.raw', '.') - if (copyin_res == 0): - SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build') - SSH.command('echo "ulimit -c unlimited && ./'+ self.air_interface +' ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - self.UELogFile = 'ue_' + self.testCase_id + '.log' - - # We are now looping several times to hope we really sync w/ an eNB - doOutterLoop = True - outterLoopCounter = 5 - gotSyncStatus = True - fullSyncStatus = True - while (doOutterLoop): - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - SSH.command('echo $USER; nohup sudo -E ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5) - time.sleep(6) - SSH.command('cd ../..', '\$', 5) - doLoop = True - loopCounter = 10 - gotSyncStatus = True - # the 'got sync' message is for the UE threads synchronization - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - # Here should never occur - logging.error('"got sync" message never showed!') - gotSyncStatus = False - doLoop = False - continue - SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - if self.air_interface == 'nr-uesoftmodem': - result = re.search('Starting sync detection', SSH.getBefore()) - else: - result = re.search('got sync', SSH.getBefore()) - if result is None: - time.sleep(10) - else: - doLoop = False - logging.debug('Found "got sync" message!') - if gotSyncStatus == False: - # we certainly need to stop the lte-uesoftmodem process if it is still running! - SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT -r *-uesoftmodem', '\$', 4) - time.sleep(3) - outterLoopCounter = outterLoopCounter - 1 - if (outterLoopCounter == 0): - doOutterLoop = False - continue - # We are now checking if sync w/ eNB DOES NOT OCCUR - # Usually during the cell synchronization stage, the UE returns with No cell synchronization message - # That is the case for LTE - # In NR case, it's a positive message that will show if synchronization occurs - doLoop = True - if self.air_interface == 'nr-uesoftmodem': - loopCounter = 10 - else: - # We are now checking if sync w/ eNB DOES NOT OCCUR - # Usually during the cell synchronization stage, the UE returns with No cell synchronization message - loopCounter = 10 - while (doLoop): - loopCounter = loopCounter - 1 - if (loopCounter == 0): - if self.air_interface == 'nr-uesoftmodem': - # Here we do have great chances that UE did NOT cell-sync w/ gNB - doLoop = False - fullSyncStatus = False - logging.debug('Never seen the NR-Sync message (Measured Carrier Frequency) --> try again') - time.sleep(6) - # Stopping the NR-UE - SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('nr-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT nr-uesoftmodem', '\$', 4) - time.sleep(6) - else: - # Here we do have a great chance that the UE did cell-sync w/ eNB - doLoop = False - doOutterLoop = False - fullSyncStatus = True - continue - SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Frequency"', '\$', 4) - if self.air_interface == 'nr-uesoftmodem': - # Positive messaging --> - result = re.search('Measured Carrier Frequency', SSH.getBefore()) - if result is not None: - doLoop = False - doOutterLoop = False - fullSyncStatus = True - else: - time.sleep(6) - else: - # Negative messaging --> - result = re.search('No cell synchronization found', SSH.getBefore()) - if result is None: - time.sleep(6) - else: - doLoop = False - fullSyncStatus = False - logging.debug('Found: "No cell synchronization" message! --> try again') - time.sleep(6) - SSH.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) - result = re.search('lte-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) - outterLoopCounter = outterLoopCounter - 1 - if (outterLoopCounter == 0): - doOutterLoop = False - - if fullSyncStatus and gotSyncStatus: - doInterfaceCheck = False - if self.air_interface == 'lte-uesoftmodem': - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is None: - doInterfaceCheck = True - # For the moment, only in explicit noS1 without kernel module (ie w/ tunnel interface) - if self.air_interface == 'nr-uesoftmodem': - result = re.search('--noS1 --nokrnmod 1', str(self.Initialize_OAI_UE_args)) - if result is not None: - doInterfaceCheck = True - if doInterfaceCheck: - SSH.command('ifconfig oaitun_ue1', '\$', 4) - SSH.command('ifconfig oaitun_ue1', '\$', 4) - # ifconfig output is different between ubuntu 16 and ubuntu 18 - result = re.search('inet addr:1|inet 1', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') - tunnelInterfaceStatus = True - else: - logging.debug(SSH.getBefore()) - logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') - tunnelInterfaceStatus = False - if RAN.eNBmbmsEnables[0]: - SSH.command('ifconfig oaitun_uem1', '\$', 4) - result = re.search('inet addr', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1m oaitun_uem1 interface is mounted and configured\u001B[0m') - tunnelInterfaceStatus = tunnelInterfaceStatus and True - else: - logging.error('\u001B[1m oaitun_uem1 interface is either NOT mounted or NOT configured\u001B[0m') - tunnelInterfaceStatus = False - else: - tunnelInterfaceStatus = True - else: - tunnelInterfaceStatus = True - - SSH.close() - if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: - HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') - logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') - if (self.ADBIPAddress != 'none'): - self.UEDevices = [] - self.UEDevices.append('OAI-UE') - self.UEDevicesStatus = [] - self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) - else: - if self.air_interface == 'lte-uesoftmodem': - if RAN.eNBmbmsEnables[0]: - HTML.htmlUEFailureMsg='oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' - else: - HTML.htmlUEFailureMsg='oaitun_ue1 interface is either NOT mounted or NOT configured' - HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') - else: - HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced' - HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') - logging.error('\033[91mInitialize OAI UE Failed! \033[0m') - self.AutoTerminateUEandeNB() - - def checkDevTTYisUnlocked(self): - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - count = 0 - while count < 5: - SSH.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10) - result = re.search('picocom', SSH.getBefore()) - if result is None: - count = 10 - else: - time.sleep(5) - count = count + 1 - SSH.close() - - def InitializeCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.enablePicocomClosure() - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - # Doing a power cycle - SSH.command('AT^RESET', 'SIMSTORE,READY', 15) - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - SSH.command('ATE1', 'OK', 5) - # Disabling the Radio - SSH.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - # Checking if auto-attach is enabled - SSH.command('AT^AUTOATT?', 'OK', 5) - result = re.search('AUTOATT: (?P[0-9\-]+)', SSH.getBefore()) - if result is not None: - if result.group('state') is not None: - autoAttachState = int(result.group('state')) - if autoAttachState is not None: - if autoAttachState == 0: - SSH.command('AT^AUTOATT=1', 'OK', 5) - logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m') - else: - logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m') - # Force closure of picocom but device might still be locked - SSH.close() - SSH.disablePicocomClosure() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def TerminateCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.enablePicocomClosure() - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - # Disabling the Radio - SSH.command('AT+CFUN=0', 'OK', 5) - logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') - SSH.close() - SSH.disablePicocomClosure() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - self.checkDevTTYisUnlocked() - - def AttachCatM(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.enablePicocomClosure() - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` - SSH.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) - SSH.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) - time.sleep(1) - # Calling twice AT to clear all buffers - SSH.command('AT', 'OK|ERROR', 5) - SSH.command('AT', 'OK', 5) - # Enabling the Radio - SSH.command('AT+CFUN=1', 'SIMSTORE,READY', 5) - logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m') - time.sleep(4) - # We should check if we register - count = 0 - attach_cnt = 0 - attach_status = False - while count < 5: - SSH.command('AT+CEREG?', 'OK', 5) - result = re.search('CEREG: 2,(?P[0-9\-]+),', SSH.getBefore()) - if result is not None: - mDataConnectionState = int(result.group('state')) - if mDataConnectionState is not None: - if mDataConnectionState == 1: - count = 10 - attach_status = True - result = re.search('CEREG: 2,1,"(?P[0-9A-Z]+)","(?P[0-9A-Z]+)"', SSH.getBefore()) - if result is not None: - networky = result.group('networky') - networkz = result.group('networkz') - logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m') - else: - logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m') - else: - logging.debug('+CEREG: 2,' + str(mDataConnectionState)) - attach_cnt = attach_cnt + 1 - else: - logging.debug(SSH.getBefore()) - attach_cnt = attach_cnt + 1 - count = count + 1 - time.sleep(1) - if attach_status: - SSH.command('AT+CESQ', 'OK', 5) - result = re.search('CESQ: 99,99,255,255,(?P[0-9]+),(?P[0-9]+)', SSH.getBefore()) - if result is not None: - nRSRQ = int(result.group('rsrq')) - nRSRP = int(result.group('rsrp')) - if (nRSRQ is not None) and (nRSRP is not None): - logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB') - logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm') - SSH.close() - SSH.disablePicocomClosure() - html_queue = SimpleQueue() - self.checkDevTTYisUnlocked() - if attach_status: - 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
' - else: - html_cell += '' - html_queue.put(html_cell) - HTML.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) - else: - logging.error('\u001B[1m CAT-M module Attachment Failed\u001B[0m') - html_cell = '
CAT-M module Attachment Failed
' - html_queue.put(html_cell) - HTML.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue) - self.AutoTerminateUEandeNB() - - def PingCatM(self): - if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - try: - statusQueue = SimpleQueue() - lock = Lock() - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) - SSH.command('cd scripts', '\$', 5) - if re.match('OAI', EPC.Type, re.IGNORECASE): - logging.debug('Using the OAI EPC HSS: not implemented yet') - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - else: - SSH.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5) - result = re.search('Allocated ipv4 addr: (?P[0-9\.]+) from Pool', SSH.getBefore()) - if result is not None: - moduleIPAddr = result.group('ipaddr') - else: - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - device_id = 'catm' - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search(', (?P[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P[0-9\.]+)\/(?P[0-9\.]+)\/(?P[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - lock.release() - SSH.close() - html_cell = '
CAT-M module\nIP Address  : ' + moduleIPAddr + '\n' + qMsg + '
' - statusQueue.put(html_cell) - if (packetLossOK): - HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue) - else: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue) - self.AutoTerminateUEandeNB() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE_common(self, device_id, statusQueue, lock, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - #RH quick add on to integrate cots control defined by yaml - #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class - #otherwise we use the legacy procedure - if COTS_UE.Check_Exists(device_id): - #switch device to Airplane mode OFF (ie Radio ON) - COTS_UE.Set_Airplane(device_id, 'OFF') - elif device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - # airplane mode off // radio on - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(2) - max_count = 45 - count = max_count - while count > 0: - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry" | grep -m 1 mDataConnectionState', '\$', 15) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\' | grep -m 1 mDataConnectionState', '\$', 60) - result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('mDataConnectionState Not Found!') - lock.release() - break - mDataConnectionState = int(result.group('state')) - if mDataConnectionState == 2: - logging.debug('\u001B[1mUE (' + device_id + ') Attach Completed\u001B[0m') - lock.acquire() - statusQueue.put(max_count - count) - statusQueue.put(device_id) - statusQueue.put('Attach Completed') - lock.release() - break - count = count - 1 - if count == 15 or count == 30: - logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m') - if self.ADBCentralized: - #RH quick add on to intgrate cots control defined by yaml - #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class - #otherwise we use the legacy procedure - if COTS_UE.Check_Exists(device_id): - #switch device to Airplane mode ON (ie Radio OFF) - COTS_UE.Set_Airplane(device_id, 'ON') - elif device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - time.sleep(0.5) - if self.ADBCentralized: - #RH quick add on to integrate cots control defined by yaml - #if device id exists in yaml dictionary, we execute the new procedre defined incots_ue class - #otherwise we use the legacy procedure - if COTS_UE.Check_Exists(device_id): - #switch device to Airplane mode OFF (ie Radio ON) - COTS_UE.Set_Airplane(device_id, 'OFF') - elif device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOnCmd[idx], '\$', 60) - time.sleep(0.5) - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until mDataConnectionState=2 (' + str(max_count-count) + ' times)\u001B[0m') - time.sleep(1) - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Attach Failed \u001B[0m') - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put('Attach Failed') - lock.release() - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def AttachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - status_queue = SimpleQueue() - lock = Lock() - nb_ue_to_connect = 0 - for device_id in self.UEDevices: - if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): - self.UEDevicesStatus[nb_ue_to_connect] = CONST.UE_STATUS_ATTACHING - p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,nb_ue_to_connect,)) - p.daemon = True - p.start() - multi_jobs.append(p) - nb_ue_to_connect = nb_ue_to_connect + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - return - else: - attach_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - attach_status = False - device_id = status_queue.get() - message = status_queue.get() - if (count < 0): - html_cell = '
UE (' + device_id + ')\n' + message + '
' - else: - html_cell = '
UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds
' - html_queue.put(html_cell) - if (attach_status): - cnt = 0 - while cnt < len(self.UEDevices): - if self.UEDevicesStatus[cnt] == CONST.UE_STATUS_ATTACHING: - self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED - cnt += 1 - HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - else: - HTML.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def DetachUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - #RH quick add on to integrate cots control defined by yaml - #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class - #otherwise we use the legacy procedure - if COTS_UE.Check_Exists(device_id): - #switch device to Airplane mode ON (ie Radio OFF) - COTS_UE.Set_Airplane(device_id,'ON') - elif device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DetachUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - cnt = 0 - for device_id in self.UEDevices: - self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHING - p = Process(target = self.DetachUE_common, args = (device_id,cnt,)) - p.daemon = True - p.start() - multi_jobs.append(p) - cnt += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) - if result is not None: - logging.debug('Waiting 5 seconds to fill up record file') - time.sleep(5) - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus[cnt] = CONST.UE_STATUS_DETACHED - cnt += 1 - - def RebootUE_common(self, device_id): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - previousmDataConnectionStates = [] - # Save mDataConnectionState - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m mDataConnectionState Not Found! \u001B[0m') - sys.exit(1) - previousmDataConnectionStates.append(int(result.group('state'))) - # Reboot UE - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell reboot', '\$', 10) - time.sleep(60) - previousmDataConnectionState = previousmDataConnectionStates.pop(0) - count = 180 - while count > 0: - count = count - 1 - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell dumpsys telephony.registry | grep mDataConnectionState', '\$', 15) - result = re.search('mDataConnectionState.*=(?P[0-9\-]+)', SSH.getBefore()) - if result is None: - mDataConnectionState = None - else: - mDataConnectionState = int(result.group('state')) - logging.debug('mDataConnectionState = ' + result.group('state')) - if mDataConnectionState is None or (previousmDataConnectionState == 2 and mDataConnectionState != 2): - logging.debug('\u001B[1mWait UE (' + device_id + ') a second until reboot completion (' + str(180-count) + ' times)\u001B[0m') - time.sleep(1) - else: - logging.debug('\u001B[1mUE (' + device_id + ') Reboot Completed\u001B[0m') - break - if count == 0: - logging.debug('\u001B[1;37;41m UE (' + device_id + ') Reboot Failed \u001B[0m') - sys.exit(1) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def RebootUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - for device_id in self.UEDevices: - p = Process(target = self.RebootUE_common, args = (device_id,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def DataDisableUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # disable data service - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data disable"', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data disable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Disabled Data Service\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataDisableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataDisableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def DataEnableUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # enable data service - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "svc data enable"\'', '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Enabled Data Service\u001B[0m') - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def DataEnableUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.DataEnableUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def GetAllUEDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('adb devices', '\$', 15) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) - SSH.close() - else: - if (os.path.isfile('./phones_list.txt')): - os.remove('./phones_list.txt') - SSH.command('ls /etc/*/phones*.txt', '\$', 5) - result = re.search('/etc/ci/phones_list.txt', SSH.getBefore()) - SSH.close() - if (result is not None) and (len(self.UEDevices) == 0): - SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, '/etc/ci/phones_list.txt', '.') - if (os.path.isfile('./phones_list.txt')): - phone_list_file = open('./phones_list.txt', 'r') - for line in phone_list_file.readlines(): - line = line.strip() - result = re.search('^#', line) - if result is not None: - continue - comma_split = line.split(",") - self.UEDevices.append(comma_split[0]) - self.UEDevicesRemoteServer.append(comma_split[1]) - self.UEDevicesRemoteUser.append(comma_split[2]) - self.UEDevicesOffCmd.append(comma_split[3]) - self.UEDevicesOnCmd.append(comma_split[4]) - self.UEDevicesRebootCmd.append(comma_split[5]) - phone_list_file.close() - - if terminate_ue_flag == True: - if len(self.UEDevices) == 0: - logging.debug('\u001B[1;37;41m UE Not Found! \u001B[0m') - sys.exit(1) - if len(self.UEDevicesStatus) == 0: - cnt = 0 - while cnt < len(self.UEDevices): - self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) - cnt += 1 - - def GetAllCatMDevices(self, terminate_ue_flag): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - #self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) - else: - if (os.path.isfile('./modules_list.txt')): - os.remove('./modules_list.txt') - SSH.command('ls /etc/*/modules*.txt', '\$', 5) - result = re.search('/etc/ci/modules_list.txt', SSH.getBefore()) - SSH.close() - if result is not None: - logging.debug('Found a module list file on ADB server') - if terminate_ue_flag == True: - if len(self.CatMDevices) == 0: - logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') - sys.exit(1) - SSH.close() - - def CheckUEStatus_common(self, lock, device_id, statusQueue, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "dumpsys telephony.registry"', '\$', 15) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "dumpsys telephony.registry"\'', '\$', 60) - result = re.search('mServiceState=(?P[0-9]+)', SSH.getBefore()) - serviceState = 'Service State: UNKNOWN' - if result is not None: - lServiceState = int(result.group('serviceState')) - if lServiceState == 3: - serviceState = 'Service State: RADIO_POWERED_OFF' - if lServiceState == 1: - serviceState = 'Service State: OUT_OF_SERVICE' - if lServiceState == 0: - serviceState = 'Service State: IN_SERVICE' - if lServiceState == 2: - serviceState = 'Service State: EMERGENCY_ONLY' - result = re.search('mDataConnectionState=(?P[0-9]+)', SSH.getBefore()) - dataConnectionState = 'Data State: UNKNOWN' - if result is not None: - lDataConnectionState = int(result.group('dataConnectionState')) - if lDataConnectionState == 0: - dataConnectionState = 'Data State: DISCONNECTED' - if lDataConnectionState == 1: - dataConnectionState = 'Data State: CONNECTING' - if lDataConnectionState == 2: - dataConnectionState = 'Data State: CONNECTED' - if lDataConnectionState == 3: - dataConnectionState = 'Data State: SUSPENDED' - result = re.search('mDataConnectionReason=(?P[0-9a-zA-Z_]+)', SSH.getBefore()) - dataConnectionReason = 'Data Reason: UNKNOWN' - if result is not None: - dataConnectionReason = 'Data Reason: ' + result.group('dataConnectionReason') - lock.acquire() - logging.debug('\u001B[1;37;44m Status Check (' + str(device_id) + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + serviceState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionState + '\u001B[0m') - logging.debug('\u001B[1;34m ' + dataConnectionReason + '\u001B[0m') - statusQueue.put(0) - statusQueue.put(device_id) - qMsg = serviceState + '\n' + dataConnectionState + '\n' + dataConnectionReason - statusQueue.put(qMsg) - lock.release() - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def CheckStatusUE(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow('N/A', 'KO', pStatus) - HTML.CreateHtmlTabFooter(False) - sys.exit(1) - multi_jobs = [] - lock = Lock() - status_queue = SimpleQueue() - i = 0 - for device_id in self.UEDevices: - p = Process(target = self.CheckUEStatus_common, args = (lock,device_id,status_queue,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd /opt/flexran_rtc', '\$', 5) - SSH.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) - SSH.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5) - result = re.search('Nb Connected UE = (?P[0-9]+)', SSH.getBefore()) - passStatus = True - if result is not None: - nb_ues = int(result.group('nb_ues')) - htmlOptions = 'Nb Connected UE(s) to eNB = ' + str(nb_ues) - logging.debug('\u001B[1;37;44m ' + htmlOptions + ' \u001B[0m') - if self.expectedNbOfConnectedUEs > -1: - if nb_ues != self.expectedNbOfConnectedUEs: - passStatus = False - else: - htmlOptions = 'N/A' - SSH.close() - else: - passStatus = True - htmlOptions = 'N/A' - - if (status_queue.empty()): - HTML.CreateHtmlTestRow(htmlOptions, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - check_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - check_status = False - device_id = status_queue.get() - message = status_queue.get() - html_cell = '
UE (' + device_id + ')\n' + message + '
' - html_queue.put(html_cell) - if check_status and passStatus: - HTML.CreateHtmlTestRowQueue(htmlOptions, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(htmlOptions, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def GetAllUEIPAddresses(self): - if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - ue_ip_status = 0 - self.UEIPAddresses = [] - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('ifconfig oaitun_ue1', '\$', 4) - result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)|inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', SSH.getBefore()) - if result is not None: - if result.group('ueipaddress') is not None: - UE_IPAddress = result.group('ueipaddress') - else: - UE_IPAddress = result.group('ueipaddress2') - logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - self.UEIPAddresses.append(UE_IPAddress) - else: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - ue_ip_status -= 1 - SSH.close() - return ue_ip_status - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - idx = 0 - for device_id in self.UEDevices: - if self.UEDevicesStatus[idx] != CONST.UE_STATUS_ATTACHED: - idx += 1 - continue - count = 0 - while count < 4: - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ip addr show | grep rmnet"', '\$', 15) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ip addr show | grep rmnet"\'', '\$', 60) - result = re.search('inet (?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\/[0-9]+[0-9a-zA-Z\.\s]+', SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m UE IP Address Not Found! \u001B[0m') - time.sleep(1) - count += 1 - else: - count = 10 - if count < 9: - ue_ip_status -= 1 - continue - UE_IPAddress = result.group('ueipaddress') - logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') - for ueipaddress in self.UEIPAddresses: - if ueipaddress == UE_IPAddress: - logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') - ue_ip_status -= 1 - continue - self.UEIPAddresses.append(UE_IPAddress) - idx += 1 - SSH.close() - return ue_ip_status - - def ping_iperf_wrong_exit(self, lock, UE_IPAddress, device_id, statusQueue, message): - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(message) - lock.release() - - def Ping_common(self, lock, UE_IPAddress, device_id, statusQueue): - try: - # Launch ping on the EPC side (true for ltebox and old open-air-cn) - # But for OAI-Rel14-CUPS, we launch from python executor - launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): - launchFromEpc = False - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - - if launchFromEpc: - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) - SSH.command('cd scripts', '\$', 5) - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) - else: - cmd = 'ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 > ping_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - ping_status = ret.returncode - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search(', (?P[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P[0-9\.]+)\/(?P[0-9\.]+)\/(?P[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - lock.acquire() - logging.debug('\u001B[1;37;44m ping result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - if (packetLossOK): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(qMsg) - lock.release() - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def PingNoS1_wrong_exit(self, qMsg): - html_queue = SimpleQueue() - html_cell = '
OAI UE ping result\n' + qMsg + '
' - html_queue.put(html_cell) - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - def PingNoS1(self): - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) - if ping_from_eNB is not None: - if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - else: - if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - try: - if ping_from_eNB is not None: - SSH.open(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword) - SSH.command('cd ' + RAN.eNBSourceCodePath + '/cmake_targets/', '\$', 5) - else: - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) - ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) - # TIMEOUT CASE - if ping_status < 0: - message = 'Ping with OAI UE crashed due to TIMEOUT!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search(', (?P[0-9\.]+)% packet loss, time [0-9\.]+ms', SSH.getBefore()) - if result is None: - message = 'Packet Loss Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - packetloss = result.group('packetloss') - if float(packetloss) == 100: - message = 'Packet Loss is 100%' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - result = re.search('rtt min\/avg\/max\/mdev = (?P[0-9\.]+)\/(?P[0-9\.]+)\/(?P[0-9\.]+)\/[0-9\.]+ ms', SSH.getBefore()) - if result is None: - message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.PingNoS1_wrong_exit(message) - return - rtt_min = result.group('rtt_min') - rtt_avg = result.group('rtt_avg') - rtt_max = result.group('rtt_max') - pal_msg = 'Packet Loss : ' + packetloss + '%' - min_msg = 'RTT(Min) : ' + rtt_min + ' ms' - avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms' - max_msg = 'RTT(Max) : ' + rtt_max + ' ms' - logging.debug('\u001B[1;37;44m OAI UE ping result \u001B[0m') - logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m') - logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m') - qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg - packetLossOK = True - if packetloss is not None: - if float(packetloss) > float(self.ping_packetloss_threshold): - qMsg += '\nPacket Loss too high' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - packetLossOK = False - elif float(packetloss) > 0: - qMsg += '\nPacket Loss is not 0%' - logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m') - SSH.close() - html_queue = SimpleQueue() - ip_addr = 'TBD' - html_cell = '
OAI UE ping result\n' + qMsg + '
' - html_queue.put(html_cell) - if packetLossOK: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - - # copying on the EPC server for logCollection - if ping_from_eNB is not None: - copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - else: - copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') - if (copyin_res == 0): - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '.log', EPC.SourceCodePath + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def Ping(self): - result = re.search('noS1', str(RAN.Initialize_eNB_args)) - if result is not None: - self.PingNoS1() - return - if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - multi_jobs = [] - i = 0 - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - HTML.CreateHtmlTestRow(self.ping_args, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - ping_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - ping_status = False - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' - html_queue.put(html_cell) - if (ping_status): - HTML.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf_ComputeTime(self): - result = re.search('-t (?P\d+)', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf time Not Found! \u001B[0m') - sys.exit(1) - return result.group('iperf_time') - - def Iperf_ComputeModifiedBW(self, idx, ue_num): - result = re.search('-b (?P[0-9\.]+)[KMG]', str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') - sys.exit(1) - iperf_bandwidth = result.group('iperf_bandwidth') - if self.iperf_profile == 'balanced': - iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if self.iperf_profile == 'single-ue': - iperf_bandwidth_new = float(iperf_bandwidth) - if self.iperf_profile == 'unbalanced': - # residual is 2% of max bw - residualBW = float(iperf_bandwidth) / 50 - if idx == 0: - iperf_bandwidth_new = float(iperf_bandwidth) - ((ue_num - 1) * residualBW) - else: - iperf_bandwidth_new = residualBW - iperf_bandwidth_str = '-b ' + iperf_bandwidth - iperf_bandwidth_str_new = '-b ' + ('%.2f' % iperf_bandwidth_new) - result = re.sub(iperf_bandwidth_str, iperf_bandwidth_str_new, str(self.iperf_args)) - if result is None: - logging.debug('\u001B[1;37;41m Calculate Iperf bandwidth Failed! \u001B[0m') - sys.exit(1) - return result - - def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - SSH.command('awk -f /tmp/tcp_iperf_stats.awk ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('Avg Bitrate : (?P[0-9\.]+ Mbits\/sec) Max Bitrate : (?P[0-9\.]+ Mbits\/sec) Min Bitrate : (?P[0-9\.]+ Mbits\/sec)', SSH.getBefore()) - if result is not None: - avgbitrate = result.group('average') - maxbitrate = result.group('maximum') - minbitrate = result.group('minimum') - lock.acquire() - logging.debug('\u001B[1;37;44m TCP iperf result (' + UE_IPAddress + ') \u001B[0m') - msg = 'TCP Stats :\n' - if avgbitrate is not None: - logging.debug('\u001B[1;34m Avg Bitrate : ' + avgbitrate + '\u001B[0m') - msg += 'Avg Bitrate : ' + avgbitrate + '\n' - if maxbitrate is not None: - logging.debug('\u001B[1;34m Max Bitrate : ' + maxbitrate + '\u001B[0m') - msg += 'Max Bitrate : ' + maxbitrate + '\n' - if minbitrate is not None: - logging.debug('\u001B[1;34m Min Bitrate : ' + minbitrate + '\u001B[0m') - msg += 'Min Bitrate : ' + minbitrate + '\n' - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - - def Iperf_analyzeV2Output(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - result = re.search('-u', str(iperf_real_options)) - if result is None: - return self.Iperf_analyzeV2TCPOutput(lock, UE_IPAddress, device_id, statusQueue, iperf_real_options) - - result = re.search('Server Report:', SSH.getBefore()) - if result is None: - result = re.search('read failed: Connection refused', SSH.getBefore()) - if result is not None: - logging.debug('\u001B[1;37;41m Could not connect to iperf server! \u001B[0m') - else: - logging.debug('\u001B[1;37;41m Server Report and Connection refused Not Found! \u001B[0m') - return -1 - # Computing the requested bandwidth in float - result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is not None: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P[0-9\.]+)%\))', SSH.getBefore()) - if result is not None: - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - jitter = result.group('jitter') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - iperfStatus = True - msg = 'Req Bitrate : ' + req_bandwidth + '\n' - logging.debug('\u001B[1;34m Req Bitrate : ' + req_bandwidth + '\u001B[0m') - if bitrate is not None: - msg += 'Bitrate : ' + bitrate + '\n' - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - result = re.search('(?P[0-9\.]+) [KMG]bits/sec', str(bitrate)) - if result is not None: - actual_bw = float(str(result.group('real_bw'))) - result = re.search('[0-9\.]+ K', bitrate) - if result is not None: - actual_bw = actual_bw * 1000 - result = re.search('[0-9\.]+ M', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000 - result = re.search('[0-9\.]+ G', bitrate) - if result is not None: - actual_bw = actual_bw * 1000000000 - br_loss = 100 * actual_bw / req_bw - bitperf = '%.2f ' % br_loss - msg += 'Bitrate Perf: ' + bitperf + '%\n' - logging.debug('\u001B[1;34m Bitrate Perf: ' + bitperf + '%\u001B[0m') - if packetloss is not None: - msg += 'Packet Loss : ' + packetloss + '%\n' - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - if float(packetloss) > float(self.iperf_packetloss_threshold): - msg += 'Packet Loss too high!\n' - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - iperfStatus = False - if jitter is not None: - msg += 'Jitter : ' + jitter + '\n' - logging.debug('\u001B[1;34m Jitter : ' + jitter + '\u001B[0m') - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - return 0 - else: - return -2 - - def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - return - # Computing the requested bandwidth in float - result = re.search('-b (?P[0-9\.]+)[KMG]', str(iperf_real_options)) - if result is None: - logging.debug('Iperf bandwidth Not Found!') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not compute Iperf bandwidth!') - return - else: - req_bandwidth = result.group('iperf_bandwidth') - req_bw = float(req_bandwidth) - result = re.search('-b [0-9\.]+K', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Kbits/sec' % req_bw - req_bw = req_bw * 1000 - result = re.search('-b [0-9\.]+M', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Mbits/sec' % req_bw - req_bw = req_bw * 1000000 - result = re.search('-b [0-9\.]+G', str(iperf_real_options)) - if result is not None: - req_bandwidth = '%.1f Gbits/sec' % req_bw - req_bw = req_bw * 1000000000 - - server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') - br_sum = 0.0 - ji_sum = 0.0 - pl_sum = 0 - ps_sum = 0 - row_idx = 0 - for line in server_file.readlines(): - result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?P[0-9\.]+ ms) +(?P[0-9]+)/ +(?P[0-9]+)', str(line)) - if result is not None: - bitrate = result.group('bitrate') - jitter = result.group('jitter') - packetlost = result.group('lostPack') - packetsent = result.group('sentPack') - br = bitrate.split(' ') - ji = jitter.split(' ') - row_idx = row_idx + 1 - curr_br = float(br[0]) - pl_sum = pl_sum + int(packetlost) - ps_sum = ps_sum + int(packetsent) - if (br[1] == 'Kbits/sec'): - curr_br = curr_br * 1000 - if (br[1] == 'Mbits/sec'): - curr_br = curr_br * 1000 * 1000 - br_sum = curr_br + br_sum - ji_sum = float(ji[0]) + ji_sum - if (row_idx > 0): - br_sum = br_sum / row_idx - ji_sum = ji_sum / row_idx - br_loss = 100 * br_sum / req_bw - if (br_sum > 1000): - br_sum = br_sum / 1000 - if (br_sum > 1000): - br_sum = br_sum / 1000 - bitrate = '%.2f Mbits/sec' % br_sum - else: - bitrate = '%.2f Kbits/sec' % br_sum - else: - bitrate = '%.2f bits/sec' % br_sum - bitperf = '%.2f ' % br_loss - bitperf += '%' - jitter = '%.2f ms' % (ji_sum) - if (ps_sum > 0): - pl = float(100 * pl_sum / ps_sum) - packetloss = '%2.1f ' % (pl) - packetloss += '%' - else: - packetloss = 'unknown' - lock.acquire() - if (br_loss < 90): - statusQueue.put(1) - else: - statusQueue.put(0) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - req_msg = 'Req Bitrate : ' + req_bandwidth - bir_msg = 'Bitrate : ' + bitrate - brl_msg = 'Bitrate Perf: ' + bitperf - jit_msg = 'Jitter : ' + jitter - pal_msg = 'Packet Loss : ' + packetloss - statusQueue.put(req_msg + '\n' + bir_msg + '\n' + brl_msg + '\n' + jit_msg + '\n' + pal_msg + '\n') - logging.debug('\u001B[1;37;45m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;35m ' + req_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + bir_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + brl_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + jit_msg + '\u001B[0m') - logging.debug('\u001B[1;35m ' + pal_msg + '\u001B[0m') - lock.release() - else: - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') - - server_file.close() - - - def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue): - result = re.search('(?P[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore()) - if result is None: - result = re.search('(?Piperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore()) - lock.acquire() - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - if result is not None: - logging.debug('\u001B[1;37;41m ' + result.group('error') + ' \u001B[0m') - statusQueue.put(result.group('error')) - else: - logging.debug('\u001B[1;37;41m Bitrate and/or Packet Loss Not Found! \u001B[0m') - statusQueue.put('Bitrate and/or Packet Loss Not Found!') - lock.release() - - bitrate = result.group('bitrate') - packetloss = result.group('packetloss') - lock.acquire() - logging.debug('\u001B[1;37;44m iperf result (' + UE_IPAddress + ') \u001B[0m') - logging.debug('\u001B[1;34m Bitrate : ' + bitrate + '\u001B[0m') - msg = 'Bitrate : ' + bitrate + '\n' - iperfStatus = True - if packetloss is not None: - logging.debug('\u001B[1;34m Packet Loss : ' + packetloss + '%\u001B[0m') - msg += 'Packet Loss : ' + packetloss + '%\n' - if float(packetloss) > float(self.iperf_packetloss_threshold): - logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m') - msg += 'Packet Loss too high!\n' - iperfStatus = False - if (iperfStatus): - statusQueue.put(0) - else: - statusQueue.put(-1) - statusQueue.put(device_id) - statusQueue.put(UE_IPAddress) - statusQueue.put(msg) - lock.release() - - def Iperf_UL_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - udpIperf = True - result = re.search('-u', str(self.iperf_args)) - if result is None: - udpIperf = False - ipnumbers = UE_IPAddress.split('.') - if (len(ipnumbers) == 4): - ipnumbers[3] = '1' - EPC_Iperf_UE_IPAddress = ipnumbers[0] + '.' + ipnumbers[1] + '.' + ipnumbers[2] + '.' + ipnumbers[3] - - # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 - # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address - launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): - launchFromEpc = False - cmd = 'hostname -I' - ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - if ret.stdout is not None: - EPC_Iperf_UE_IPAddress = ret.stdout.strip() - port = 5001 + idx - if launchFromEpc: - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if udpIperf: - SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5) - else: - SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5) - SSH.close() - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - if udpIperf: - cmd = 'nohup ' + prefix + 'iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - else: - cmd = 'nohup ' + prefix + 'iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log 2>&1 &' - logging.debug(cmd) - subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') - time.sleep(0.5) - - # Launch iperf client on UE - if (device_id == 'OAI-UE'): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - else: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - SSH.command('cd ' + EPC.SourceCodePath+ '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - modified_options = modified_options.replace('-R','') - time.sleep(0.5) - - SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if (device_id == 'OAI-UE'): - iperf_status = SSH.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ADBCentralized: - iperf_status = SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - iperf_status = SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '"\' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - SSH.command('fromdos -o iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - SSH.command('cat iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - # TIMEOUT Case - if iperf_status < 0: - SSH.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - SSH.close() - - # Kill iperf server on EPC side - if launchFromEpc: - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5) - SSH.close() - else: - cmd = 'killall --signal SIGKILL iperf' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - time.sleep(1) - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') - # in case of failure, retrieve server log - if (clientStatus == -1) or (clientStatus == -2): - if launchFromEpc: - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - # in case of OAI-UE - if (device_id == 'OAI-UE'): - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') - - def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): - try: - # Single-UE profile -- iperf only on one UE - if self.iperf_profile == 'single-ue' and idx != 0: - return - useIperf3 = False - udpIperf = True - - self.ueIperfVersion = '2.0.5' - if (device_id != 'OAI-UE'): - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - SSH.command('if [ ! -d ' + EPC.SourceCodePath + '/scripts ]; then mkdir -p ' + EPC.SourceCodePath + '/scripts ; fi', '\$', 5) - SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) - # Checking if iperf / iperf3 are installed - if self.ADBCentralized: - SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ls /data/local/tmp"\'', '\$', 60) - result = re.search('iperf3', SSH.getBefore()) - if result is None: - result = re.search('iperf', SSH.getBefore()) - if result is None: - message = 'Neither iperf nor iperf3 installed on UE!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - SSH.close() - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - else: - if self.ADBCentralized: - SSH.command('adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf --version"\'', '\$', 60) - result = re.search('iperf version 2.0.5', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.10' - else: - useIperf3 = True - SSH.close() - else: - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('iperf --version', '\$', 5) - result = re.search('iperf version 2.0.5', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.5' - result = re.search('iperf version 2.0.10', SSH.getBefore()) - if result is not None: - self.ueIperfVersion = '2.0.10' - SSH.close() - # in case of iperf, UL has its own function - if (not useIperf3): - result = re.search('-R', str(self.iperf_args)) - if result is not None: - self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue) - return - - # Launch the IPERF server on the UE side for DL - if (device_id == 'OAI-UE'): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - udpIperf = False - else: - SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) - else: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) - if self.ADBCentralized: - if (useIperf3): - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) - else: - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - result = re.search('-u', str(self.iperf_args)) - if result is None: - SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - udpIperf = False - else: - SSH.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) - else: - SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - SSH.command('echo $USER; nohup ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" \' 2>&1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 60) - - time.sleep(0.5) - SSH.close() - - # Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn - # But for OAI-Rel14-CUPS, we launch from python executor - launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): - launchFromEpc = False - if launchFromEpc: - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) - iperf_time = self.Iperf_ComputeTime() - time.sleep(0.5) - - if udpIperf: - modified_options = self.Iperf_ComputeModifiedBW(idx, ue_num) - else: - modified_options = str(self.iperf_args) - time.sleep(0.5) - - if launchFromEpc: - SSH.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - else: - if (os.path.isfile('iperf_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_' + self.testCase_id + '_' + device_id + '.log') - if (useIperf3): - SSH.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - - clientStatus = 0 - self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) - else: - if launchFromEpc: - iperf_status = SSH.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) - else: - if self.ueIperfVersion == self.dummyIperfVersion: - prefix = '' - else: - prefix = '' - if self.ueIperfVersion == '2.0.5': - prefix = '/opt/iperf-2.0.5/bin/' - cmd = prefix + 'iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 > iperf_' + self.testCase_id + '_' + device_id + '.log' - message = cmd + '\n' - logging.debug(cmd) - ret = subprocess.run(cmd, shell=True) - iperf_status = ret.returncode - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cat ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - if iperf_status < 0: - if launchFromEpc: - SSH.close() - message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) - SSH.close() - - # Kill the IPERF server that runs in background - if (device_id == 'OAI-UE'): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('killall iperf', '\$', 5) - else: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps" | grep --color=never iperf | grep -v grep\'', '\$', 60) - result = re.search('shell +(?P\d+)', SSH.getBefore()) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - SSH.close() - # if the client report is absent, try to analyze the server log file - if (clientStatus == -1): - time.sleep(1) - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - if (device_id == 'OAI-UE'): - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - else: - SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.SourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - # fromdos has to be called on the python executor not on ADB server - cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log' - subprocess.run(cmd, shell=True) - self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) - - # in case of OAI UE: - if (device_id == 'OAI-UE'): - if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): - if not launchFromEpc: - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') - else: - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def IperfNoS1(self): - if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - check_OAI_UE = True - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - server_on_enb = re.search('-R', str(self.iperf_args)) - if server_on_enb is not None: - iServerIPAddr = RAN.eNBIPAddress - iServerUser = RAN.eNBUserName - iServerPasswd = RAN.eNBPassword - iClientIPAddr = self.UEIPAddress - iClientUser = self.UEUserName - iClientPasswd = self.UEPassword - else: - iServerIPAddr = self.UEIPAddress - iServerUser = self.UEUserName - iServerPasswd = self.UEPassword - iClientIPAddr = RAN.eNBIPAddress - iClientUser = RAN.eNBUserName - iClientPasswd = RAN.eNBPassword - if self.iperf_options != 'sink': - # Starting the iperf server - SSH.open(iServerIPAddr, iServerUser, iServerPasswd) - # args SHALL be "-c client -u any" - # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 - # -B 10.0.1.1 -u -s -i 1 -fm - server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) - server_options = server_options.replace('-c','-B') - SSH.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) - SSH.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) - time.sleep(0.5) - SSH.close() - - # Starting the iperf client - modified_options = self.Iperf_ComputeModifiedBW(0, 1) - modified_options = modified_options.replace('-R','') - iperf_time = self.Iperf_ComputeTime() - SSH.open(iClientIPAddr, iClientUser, iClientPasswd) - SSH.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) - iperf_status = SSH.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) - status_queue = SimpleQueue() - lock = Lock() - if iperf_status < 0: - message = 'iperf on OAI UE crashed due to TIMEOUT !' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - clientStatus = -2 - else: - if self.iperf_options == 'sink': - clientStatus = 0 - status_queue.put(0) - status_queue.put('OAI-UE') - status_queue.put('10.0.1.2') - status_queue.put('Sink Test : no check') - else: - clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) - SSH.close() - - # Stopping the iperf server - if self.iperf_options != 'sink': - SSH.open(iServerIPAddr, iServerUser, iServerPasswd) - SSH.command('killall --signal SIGKILL iperf', '\$', 5) - time.sleep(0.5) - SSH.close() - - if (clientStatus == -1): - if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): - os.remove('iperf_server_' + self.testCase_id + '.log') - SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') - self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) - - # copying on the EPC server for logCollection - if (clientStatus == -1): - copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts') - copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') - if (copyin_res == 0): - SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts') - iperf_noperf = False - if status_queue.empty(): - iperf_status = False - else: - iperf_status = True - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def Iperf(self): - result = re.search('noS1', str(RAN.Initialize_eNB_args)) - if result is not None: - self.IperfNoS1() - return - if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - check_eNB = True - if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): - check_OAI_UE = True - else: - check_OAI_UE = False - pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) - if (pStatus < 0): - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) - self.AutoTerminateUEandeNB() - return - ueIpStatus = self.GetAllUEIPAddresses() - if (ueIpStatus < 0): - logging.debug('going here') - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.UE_IP_ADDRESS_ISSUE) - self.AutoTerminateUEandeNB() - return - - self.dummyIperfVersion = '2.0.10' - #cmd = 'iperf --version' - #logging.debug(cmd + '\n') - #iperfStdout = subprocess.check_output(cmd, shell=True, universal_newlines=True) - #result = re.search('iperf version 2.0.5', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.5' - #result = re.search('iperf version 2.0.10', str(iperfStdout.strip())) - #if result is not None: - # dummyIperfVersion = '2.0.10' - - multi_jobs = [] - i = 0 - ue_num = len(self.UEIPAddresses) - lock = Lock() - status_queue = SimpleQueue() - for UE_IPAddress in self.UEIPAddresses: - device_id = self.UEDevices[i] - p = Process(target = self.Iperf_common, args = (lock,UE_IPAddress,device_id,i,ue_num,status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i = i + 1 - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - HTML.CreateHtmlTestRow(self.iperf_args, 'KO', CONST.ALL_PROCESSES_OK) - self.AutoTerminateUEandeNB() - else: - iperf_status = True - iperf_noperf = False - html_queue = SimpleQueue() - while (not status_queue.empty()): - count = status_queue.get() - if (count < 0): - iperf_status = False - if (count > 0): - iperf_noperf = True - device_id = status_queue.get() - ip_addr = status_queue.get() - message = status_queue.get() - html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' - html_queue.put(html_cell) - if (iperf_noperf and iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) - elif (iperf_status): - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) - self.AutoTerminateUEandeNB() - - def CheckProcessExist(self, check_eNB, check_OAI_UE): - multi_jobs = [] - status_queue = SimpleQueue() - # in noS1 config, no need to check status from EPC - # in gNB also currently no need to check - result = re.search('noS1|band78', str(RAN.Initialize_eNB_args)) - if result is None: - p = Process(target = EPC.CheckHSSProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = EPC.CheckMMEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = EPC.CheckSPGWProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - else: - if (check_eNB == False) and (check_OAI_UE == False): - return 0 - if check_eNB: - p = Process(target = RAN.CheckeNBProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - if check_OAI_UE: - p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == CONST.ENB_PROCESS_FAILED: - fileCheck = re.search('enb_', str(RAN.eNBLogFiles[0])) - if fileCheck is not None: - SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/' + RAN.eNBLogFiles[0], '.') - logStatus = RAN.AnalyzeLogFile_eNB(RAN.eNBLogFiles[0]) - if logStatus < 0: - result = logStatus - RAN.eNBLogFiles[0]='' - if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: - self.TerminateFlexranCtrl() - return result - - def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag): - multi_jobs = [] - status_queue = SimpleQueue() - if initialize_OAI_UE_flag == False: - p = Process(target = self.CheckOAIUEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - for job in multi_jobs: - job.join() - - if (status_queue.empty()): - return -15 - else: - result = 0 - while (not status_queue.empty()): - status = status_queue.get() - if (status < 0): - result = status - if result == CONST.OAI_UE_PROCESS_FAILED: - fileCheck = re.search('ue_', str(self.UELogFile)) - if fileCheck is not None: - SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - if logStatus < 0: - result = logStatus - return result - - def CheckOAIUEProcess(self, status_queue): - try: - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + ' | grep -v grep', '\$', 5) - result = re.search(self.air_interface, SSH.getBefore()) - if result is None: - logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') - status_queue.put(CONST.OAI_UE_PROCESS_FAILED) - else: - status_queue.put(CONST.OAI_UE_PROCESS_OK) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - - def AnalyzeLogFile_UE(self, UElogFile): - if (not os.path.isfile('./' + UElogFile)): - return -1 - ue_log_file = open('./' + UElogFile, 'r') - exitSignalReceived = False - foundAssertion = False - msgAssertion = '' - msgLine = 0 - foundSegFault = False - foundRealTimeIssue = False - uciStatMsgCount = 0 - pdcpDataReqFailedCount = 0 - badDciCount = 0 - f1aRetransmissionCount = 0 - fatalErrorCount = 0 - macBsrTimerExpiredCount = 0 - rrcConnectionRecfgComplete = 0 - no_cell_sync_found = False - mib_found = False - frequency_found = False - plmn_found = False - nrUEFlag = False - nrDecodeMib = 0 - nrFoundDCI = 0 - nrCRCOK = 0 - mbms_messages = 0 - HTML.htmlUEFailureMsg='' - global_status = CONST.ALL_PROCESSES_OK - for line in ue_log_file.readlines(): - result = re.search('nr_synchro_time', str(line)) - if result is not None: - nrUEFlag = True - if nrUEFlag: - result = re.search('decode mib', str(line)) - if result is not None: - nrDecodeMib += 1 - result = re.search('found 1 DCIs', str(line)) - if result is not None: - nrFoundDCI += 1 - result = re.search('CRC OK', str(line)) - if result is not None: - nrCRCOK += 1 - result = re.search('Exiting OAI softmodem', str(line)) - if result is not None: - exitSignalReceived = True - result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('./lte-uesoftmodem', str(line)) - if result is not None and not exitSignalReceived: - foundSegFault = True - result = re.search('[Aa]ssertion', str(line)) - if result is not None and not exitSignalReceived: - foundAssertion = True - result = re.search('LLL', str(line)) - if result is not None and not exitSignalReceived: - foundRealTimeIssue = True - if foundAssertion and (msgLine < 3): - msgLine += 1 - msgAssertion += str(line) - result = re.search('uci->stat', str(line)) - if result is not None and not exitSignalReceived: - uciStatMsgCount += 1 - result = re.search('PDCP data request failed', str(line)) - if result is not None and not exitSignalReceived: - pdcpDataReqFailedCount += 1 - result = re.search('bad DCI 1', str(line)) - if result is not None and not exitSignalReceived: - badDciCount += 1 - result = re.search('Format1A Retransmission but TBS are different', str(line)) - if result is not None and not exitSignalReceived: - f1aRetransmissionCount += 1 - result = re.search('FATAL ERROR', str(line)) - if result is not None and not exitSignalReceived: - fatalErrorCount += 1 - result = re.search('MAC BSR Triggered ReTxBSR Timer expiry', str(line)) - if result is not None and not exitSignalReceived: - macBsrTimerExpiredCount += 1 - result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) - if result is not None: - rrcConnectionRecfgComplete += 1 - # No cell synchronization found, abandoning - result = re.search('No cell synchronization found, abandoning', str(line)) - if result is not None: - no_cell_sync_found = True - if RAN.eNBmbmsEnables[0]: - result = re.search('TRIED TO PUSH MBMS DATA', str(line)) - if result is not None: - mbms_messages += 1 - result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P\d{1,3}), N_RB_DL (?P\d{1,3}), PHICH DURATION (?P\d), PHICH RESOURCE (?P.{1,4}), TX_ANT (?P\d)", str(line)) - if result is not None and (not mib_found): - try: - mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " nidcell = " + result.group('nidcell') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " n_rb_dl = " + result.group('n_rb_dl') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_duration = " + result.group('phich_duration') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " phich_resource = " + result.group('phich_resource') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mibMsg = " tx_ant = " + result.group('tx_ant') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - mib_found = True - except Exception as e: - logging.error('\033[91m' + "MIB marker was not found" + '\033[0m') - result = re.search("Measured Carrier Frequency (?P\d{1,15}) Hz", str(line)) - if result is not None and (not frequency_found): - try: - mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - frequency_found = True - except Exception as e: - logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m') - result = re.search("PLMN MCC (?P\d{1,3}), MNC (?P\d{1,3}), TAC", str(line)) - if result is not None and (not plmn_found): - try: - mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - plmn_found = True - except Exception as e: - logging.error('\033[91m' + "PLMN not found" + '\033[0m') - result = re.search("Found (?P[\w,\s]{1,15}) \(name from internal table\)", str(line)) - if result is not None: - try: - mibMsg = "The operator is: " + result.group('operator') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "Operator name not found" + '\033[0m') - result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line)) - if result is not None: - try: - mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + ' -> ' - logging.debug('\033[94m' + mibMsg + '\033[0m') - except Exception as e: - logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') - result = re.search("DL Carrier Frequency/ARFCN : \-*(?P\d{1,15}/\d{1,4})", str(line)) - if result is not None: - try: - freq = result.group('carrier_frequency') - new_freq = re.sub('/[0-9]+','',freq) - float_freq = float(new_freq) / 1000000 - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' - logging.debug('\033[94m' + " DL Carrier Frequency is: " + str(freq) + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') - result = re.search("AllowedMeasBandwidth : (?P\d{1,7})", str(line)) - if result is not None: - try: - prb = result.group('allowed_bandwidth') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + ' -- PRB: ' + prb + '\n' - logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') - except Exception as e: - logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') - ue_log_file.close() - if rrcConnectionRecfgComplete > 0: - statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' - logging.debug('\033[94m' + statMsg + '\033[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nrUEFlag: - if nrDecodeMib > 0: - statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nrFoundDCI > 0: - statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if nrCRCOK > 0: - statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if not frequency_found: - statMsg = 'NR-UE could NOT synch!' - logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if uciStatMsgCount > 0: - statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if pdcpDataReqFailedCount > 0: - statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if badDciCount > 0: - statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if f1aRetransmissionCount > 0: - statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if fatalErrorCount > 0: - statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if macBsrTimerExpiredCount > 0: - statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if RAN.eNBmbmsEnables[0]: - if mbms_messages > 0: - statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' - logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - else: - statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' - logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m') - global_status = CONST.OAI_UE_PROCESS_NO_MBMS_MSGS - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' - if foundSegFault: - logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') - if not nrUEFlag: - global_status = CONST.OAI_UE_PROCESS_SEG_FAULT - else: - if not frequency_found: - global_status = CONST.OAI_UE_PROCESS_SEG_FAULT - if foundAssertion: - logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE showed an assertion!\n' - if not nrUEFlag: - if not mib_found or not frequency_found: - global_status = CONST.OAI_UE_PROCESS_ASSERTION - else: - if not frequency_found: - global_status = CONST.OAI_UE_PROCESS_ASSERTION - if foundRealTimeIssue: - logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE faced real time issues!\n' - if nrUEFlag: - if not frequency_found: - global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC - else: - if no_cell_sync_found and not mib_found: - logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') - HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE could not synchronize!\n' - global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC - return global_status - - - def TerminateFlexranCtrl(self): - if RAN.flexranCtrlInstalled == False or RAN.flexranCtrlStarted == False: - return - if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': - HELP.GenericHelp(CONST.Version) - sys.exit('Insufficient Parameter') - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) - time.sleep(1) - SSH.command('echo ' + EPC.Password + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) - time.sleep(1) - SSH.close() - RAN.flexranCtrlStarted=False - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def TerminateUE_common(self, device_id, idx): - try: - SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # back in airplane mode on (ie radio off) - if self.ADBCentralized: - #RH quick add on to intgrate cots control defined by yaml - #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class - #otherwise we use the legacy procedure - if COTS_UE.Check_Exists(device_id): - #switch device to Airplane mode ON (ie Radio OFF) - COTS_UE.Set_Airplane(device_id, 'ON') - elif device_id == '84B7N16418004022': - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60) - else: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60) - logging.debug('\u001B[1mUE (' + device_id + ') Detach Completed\u001B[0m') - - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "ps | grep --color=never iperf | grep -v grep"\'', '\$', 60) - result = re.search('shell +(?P\d+)', SSH.getBefore()) - if result is not None: - pid_iperf = result.group('pid') - if self.ADBCentralized: - SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"', '\$', 5) - else: - SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' \'adb -s ' + device_id + ' shell "kill -KILL ' + pid_iperf + '"\'', '\$', 60) - SSH.close() - except: - os.kill(os.getppid(),signal.SIGUSR1) - - def TerminateUE(self): - terminate_ue_flag = False - self.GetAllUEDevices(terminate_ue_flag) - multi_jobs = [] - i = 0 - for device_id in self.UEDevices: - p = Process(target= self.TerminateUE_common, args = (device_id,i,)) - p.daemon = True - p.start() - multi_jobs.append(p) - i += 1 - for job in multi_jobs: - job.join() - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def TerminateOAIUE(self): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) - SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT -r .*-uesoftmodem || true', '\$', 5) - time.sleep(10) - SSH.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-uesoftmodem', SSH.getBefore()) - if result is not None: - SSH.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL -r .*-uesoftmodem || true', '\$', 5) - time.sleep(5) - SSH.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.close() - result = re.search('ue_', str(self.UELogFile)) - if result is not None: - copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') - if (copyin_res == -1): - logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') - HTML.htmlUEFailureMsg='Could not copy UE logfile to analyze it!' - HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') - self.UELogFile = '' - return - logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_UE(self.UELogFile) - result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) - if result is not None: - ueAction = 'Sniffing' - else: - ueAction = 'Connection' - if (logStatus < 0): - logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') - HTML.htmlUEFailureMsg='' + ueAction + ' Failed\n' + HTML.htmlUEFailureMsg - HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - if self.air_interface == 'lte-uesoftmodem': - # In case of sniffing on commercial eNBs we have random results - # Not an error then - if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): - self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB() - else: - if (logStatus == CONST.OAI_UE_PROCESS_COULD_NOT_SYNC): - self.Initialize_OAI_UE_args = '' - self.AutoTerminateUEandeNB() - else: - logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') - HTML.htmlUEFailureMsg='' + ueAction + ' Completed\n' + HTML.htmlUEFailureMsg - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - self.UELogFile = '' - else: - HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - - def AutoTerminateUEandeNB(self): - if (self.ADBIPAddress != 'none'): - self.testCase_id = 'AUTO-KILL-UE' - HTML.testCase_id=self.testCase_id - self.desc = 'Automatic Termination of UE' - HTML.desc='Automatic Termination of UE' - self.ShowTestID() - self.TerminateUE() - if (self.Initialize_OAI_UE_args != ''): - self.testCase_id = 'AUTO-KILL-OAI-UE' - HTML.testCase_id=self.testCase_id - self.desc = 'Automatic Termination of OAI-UE' - HTML.desc='Automatic Termination of OAI-UE' - self.ShowTestID() - self.TerminateOAIUE() - if (RAN.Initialize_eNB_args != ''): - self.testCase_id = 'AUTO-KILL-eNB' - HTML.testCase_id=self.testCase_id - self.desc = 'Automatic Termination of eNB' - HTML.desc='Automatic Termination of eNB' - self.ShowTestID() - RAN.eNB_instance=0 - RAN.TerminateeNB() - if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: - self.testCase_id = 'AUTO-KILL-flexran-ctl' - HTML.testCase_id=self.testCase_id - self.desc = 'Automatic Termination of FlexRan CTL' - HTML.desc='Automatic Termination of FlexRan CTL' - self.ShowTestID() - self.TerminateFlexranCtrl() - RAN.prematureExit=True - - def IdleSleep(self): - time.sleep(self.idle_sleep_time) - HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK) - - def X2_Status(self, idx, fileName): - cmd = "curl --silent http://" + EPC.IPAddress + ":9999/stats | jq '.' > " + fileName - message = cmd + '\n' - logging.debug(cmd) - subprocess.run(cmd, shell=True) - if idx == 0: - cmd = "jq '.mac_stats | length' " + fileName - strNbEnbs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2NbENBs = int(strNbEnbs.strip()) - cnt = 0 - while cnt < self.x2NbENBs: - cmd = "jq '.mac_stats[" + str(cnt) + "].bs_id' " + fileName - bs_id = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBBsIds[idx].append(bs_id.strip()) - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats | length' " + fileName - stNbUEs = subprocess.check_output(cmd, shell=True, universal_newlines=True) - nbUEs = int(stNbUEs.strip()) - ueIdx = 0 - self.x2ENBConnectedUEs[idx].append([]) - while ueIdx < nbUEs: - cmd = "jq '.mac_stats[" + str(cnt) + "].ue_mac_stats[" + str(ueIdx) + "].rnti' " + fileName - rnti = subprocess.check_output(cmd, shell=True, universal_newlines=True) - self.x2ENBConnectedUEs[idx][cnt].append(rnti.strip()) - ueIdx += 1 - cnt += 1 - - msg = "FlexRan Controller is connected to " + str(self.x2NbENBs) + " eNB(s)" - logging.debug(msg) - message += msg + '\n' - cnt = 0 - while cnt < self.x2NbENBs: - msg = " -- eNB: " + str(self.x2ENBBsIds[idx][cnt]) + " is connected to " + str(len(self.x2ENBConnectedUEs[idx][cnt])) + " UE(s)" - logging.debug(msg) - message += msg + '\n' - ueIdx = 0 - while ueIdx < len(self.x2ENBConnectedUEs[idx][cnt]): - msg = " -- UE rnti: " + str(self.x2ENBConnectedUEs[idx][cnt][ueIdx]) - logging.debug(msg) - message += msg + '\n' - ueIdx += 1 - cnt += 1 - return message - - def Perform_X2_Handover(self): - html_queue = SimpleQueue() - fullMessage = '
'
-		msg = 'Doing X2 Handover w/ option ' + self.x2_ho_options
-		logging.debug(msg)
-		fullMessage += msg + '\n'
-		if self.x2_ho_options == 'network':
-			if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted:
-				self.x2ENBBsIds = []
-				self.x2ENBConnectedUEs = []
-				self.x2ENBBsIds.append([])
-				self.x2ENBBsIds.append([])
-				self.x2ENBConnectedUEs.append([])
-				self.x2ENBConnectedUEs.append([])
-				fullMessage += self.X2_Status(0, self.testCase_id + '_pre_ho.json') 
-
-				msg = "Activating the X2 Net control on each eNB"
-				logging.debug(msg)
-				fullMessage += msg + '\n'
-				eNB_cnt = self.x2NbENBs
-				cnt = 0
-				while cnt < eNB_cnt:
-					cmd = "curl -XPOST http://" + EPC.IPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1"
-					logging.debug(cmd)
-					fullMessage += cmd + '\n'
-					subprocess.run(cmd, shell=True)
-					cnt += 1
-				# Waiting for the activation to be active
-				time.sleep(10)
-				msg = "Switching UE(s) from eNB to eNB"
-				logging.debug(msg)
-				fullMessage += msg + '\n'
-				cnt = 0
-				while cnt < eNB_cnt:
-					ueIdx = 0
-					while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]):
-						cmd = "curl -XPOST http://" + EPC.IPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1])
-						logging.debug(cmd)
-						fullMessage += cmd + '\n'
-						subprocess.run(cmd, shell=True)
-						ueIdx += 1
-					cnt += 1
-				time.sleep(10)
-				# check
-				logging.debug("Checking the Status after X2 Handover")
-				fullMessage += self.X2_Status(1, self.testCase_id + '_post_ho.json') 
-				cnt = 0
-				x2Status = True
-				while cnt < eNB_cnt:
-					if len(self.x2ENBConnectedUEs[0][cnt]) == len(self.x2ENBConnectedUEs[1][cnt]):
-						x2Status = False
-					cnt += 1
-				if x2Status:
-					msg = "X2 Handover was successful"
-					logging.debug(msg)
-					fullMessage += msg + '
' - html_queue.put(fullMessage) - HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - msg = "X2 Handover FAILED" - logging.error(msg) - fullMessage += msg + '' - html_queue.put(fullMessage) - HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - else: - HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK) - - def LogCollectBuild(self): - if (RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != ''): - IPAddress = RAN.eNBIPAddress - UserName = RAN.eNBUserName - Password = RAN.eNBPassword - SourceCodePath = RAN.eNBSourceCodePath - elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - SourceCodePath = self.UESourceCodePath - else: - sys.exit('Insufficient Parameter') - SSH.open(IPAddress, UserName, Password) - SSH.command('cd ' + SourceCodePath, '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('rm -f build.log.zip', '\$', 5) - SSH.command('zip build.log.zip build_log_*/*', '\$', 60) - SSH.close() - def LogCollectPing(self): - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) - SSH.command('cd scripts', '\$', 5) - SSH.command('rm -f ping.log.zip', '\$', 5) - SSH.command('zip ping.log.zip ping*.log', '\$', 60) - SSH.command('rm ping*.log', '\$', 5) - SSH.close() - - def LogCollectIperf(self): - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) - SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) - SSH.command('cd scripts', '\$', 5) - SSH.command('rm -f iperf.log.zip', '\$', 5) - SSH.command('zip iperf.log.zip iperf*.log', '\$', 60) - SSH.command('rm iperf*.log', '\$', 5) - SSH.close() - - def LogCollectOAIUE(self): - SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('cd ' + self.UESourceCodePath, '\$', 5) - SSH.command('cd cmake_targets', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5) - SSH.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60) - SSH.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5) - SSH.close() - - def RetrieveSystemVersion(self, machine): - if RAN.eNBIPAddress == 'none' or self.UEIPAddress == 'none': - HTML.OsVersion[0]='Ubuntu 16.04.5 LTS' - HTML.KernelVersion[0]='4.15.0-45-generic' - HTML.UhdVersion[0]='3.13.0.1-0' - HTML.UsrpBoard[0]='B210' - HTML.CpuNb[0]='4' - HTML.CpuModel[0]='Intel(R) Core(TM) i5-6200U' - HTML.CpuMHz[0]='2399.996 MHz' - return 0 - if machine == 'eNB': - if RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != '': - IPAddress = RAN.eNBIPAddress - UserName = RAN.eNBUserName - Password = RAN.eNBPassword - idx = 0 - else: - return -1 - if machine == 'UE': - if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': - IPAddress = self.UEIPAddress - UserName = self.UEUserName - Password = self.UEPassword - idx = 1 - else: - return -1 - - SSH.open(IPAddress, UserName, Password) - SSH.command('lsb_release -a', '\$', 5) - result = re.search('Description:\\\\t(?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) - if result is not None: - OsVersion = result.group('os_type') - logging.debug('OS is: ' + OsVersion) - HTML.OsVersion[idx]=OsVersion - else: - SSH.command('hostnamectl', '\$', 5) - result = re.search('Operating System: (?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) - if result is not None: - OsVersion = result.group('os_type') - if OsVersion == 'CentOS Linux 7 ': - SSH.command('cat /etc/redhat-release', '\$', 5) - result = re.search('CentOS Linux release (?P[0-9\.]+)', SSH.getBefore()) - if result is not None: - OsVersion = OsVersion.replace('7 ', result.group('os_version')) - logging.debug('OS is: ' + OsVersion) - HTML.OsVersion[idx]=OsVersion - SSH.command('uname -r', '\$', 5) - result = re.search('uname -r\\\\r\\\\n(?P[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) - if result is not None: - KernelVersion = result.group('kernel_version') - logging.debug('Kernel Version is: ' + KernelVersion) - HTML.KernelVersion[idx]=KernelVersion - SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) - result = re.search('libuhd003:amd64 *(?P[0-9\.]+)', SSH.getBefore()) - if result is not None: - UhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + UhdVersion) - HTML.UhdVersion[idx]=UhdVersion - else: - SSH.command('uhd_config_info --version', '\$', 5) - result = re.search('UHD (?P[a-zA-Z0-9\.\-]+)', SSH.getBefore()) - if result is not None: - UhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + UhdVersion) - HTML.UhdVersion[idx]=UhdVersion - SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60) - usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) - count = 0 - for board in usrp_boards: - if count == 0: - UsrpBoard = board - else: - UsrpBoard += ',' + board - count += 1 - if count > 0: - logging.debug('USRP Board(s) : ' + UsrpBoard) - HTML.UsrpBoard[idx]=UsrpBoard - SSH.command('lscpu', '\$', 5) - result = re.search('CPU\(s\): *(?P[0-9]+).*Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P[0-9\.]+)', SSH.getBefore()) - if result is not None: - CpuNb = result.group('nb_cpus') - logging.debug('nb_cpus: ' + CpuNb) - HTML.CpuNb[idx]=CpuNb - CpuModel = result.group('model') - logging.debug('model: ' + CpuModel) - HTML.CpuModel[idx]=CpuModel - CpuMHz = result.group('cpu_mhz') + ' MHz' - logging.debug('cpu_mhz: ' + CpuMHz) - HTML.CpuMHz[idx]=CpuMHz - SSH.close() - - def ShowTestID(self): - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') - logging.debug('\u001B[1m' + self.desc + '\u001B[0m') - logging.debug('\u001B[1m----------------------------------------\u001B[0m') - - #----------------------------------------------------------- # General Functions @@ -3144,24 +99,34 @@ def AssignParams(params_dict): def GetParametersFromXML(action): - if action == 'Build_eNB': + if action == 'Build_eNB' or action == 'Build_Image': RAN.Build_eNB_args=test.findtext('Build_eNB_args') + CONTAINERS.imageKind=test.findtext('kind') forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') if (forced_workspace_cleanup is None): RAN.Build_eNB_forced_workspace_cleanup=False + CONTAINERS.forcedWorkspaceCleanup=False else: if re.match('true', forced_workspace_cleanup, re.IGNORECASE): RAN.Build_eNB_forced_workspace_cleanup=True + CONTAINERS.forcedWorkspaceCleanup=True else: - RAN.Build_eNB_forced_workspace_cleanup=False + RAN.Build_eNB_forced_workspace_cleanup=True + CONTAINERS.forcedWorkspaceCleanup=False eNB_instance=test.findtext('eNB_instance') if (eNB_instance is None): RAN.eNB_instance=0 + CONTAINERS.eNB_instance=0 else: RAN.eNB_instance=int(eNB_instance) - RAN.eNB_serverId=test.findtext('eNB_serverId') - if (RAN.eNB_serverId is None): - RAN.eNB_serverId='0' + CONTAINERS.eNB_instance=int(eNB_instance) + eNB_serverId=test.findtext('eNB_serverId') + if (eNB_serverId is None): + RAN.eNB_serverId[RAN.eNB_instance]='0' + CONTAINERS.eNB_serverId[RAN.eNB_instance]='0' + else: + RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId + CONTAINERS.eNB_serverId[CONTAINERS.eNB_instance]=eNB_serverId xmlBgBuildField = test.findtext('backgroundBuild') if (xmlBgBuildField is None): RAN.backgroundBuild=False @@ -3178,9 +143,11 @@ def GetParametersFromXML(action): RAN.eNB_instance=0 else: RAN.eNB_instance=int(eNB_instance) - RAN.eNB_serverId=test.findtext('eNB_serverId') - if (RAN.eNB_serverId is None): - RAN.eNB_serverId='0' + eNB_serverId=test.findtext('eNB_serverId') + if (eNB_serverId is None): + RAN.eNB_serverId[RAN.eNB_instance]='0' + else: + RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId elif action == 'Initialize_eNB': RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args') @@ -3189,9 +156,11 @@ def GetParametersFromXML(action): RAN.eNB_instance=0 else: RAN.eNB_instance=int(eNB_instance) - RAN.eNB_serverId=test.findtext('eNB_serverId') - if (RAN.eNB_serverId is None): - RAN.eNB_serverId='0' + eNB_serverId=test.findtext('eNB_serverId') + if (eNB_serverId is None): + RAN.eNB_serverId[RAN.eNB_instance]='0' + else: + RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId #local variable air_interface air_interface = test.findtext('air_interface') @@ -3208,10 +177,12 @@ def GetParametersFromXML(action): RAN.eNB_instance=0 else: RAN.eNB_instance=int(eNB_instance) - RAN.eNB_serverId=test.findtext('eNB_serverId') - if (RAN.eNB_serverId is None): - RAN.eNB_serverId='0' - + eNB_serverId=test.findtext('eNB_serverId') + if (eNB_serverId is None): + RAN.eNB_serverId[RAN.eNB_instance]='0' + else: + RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId + #local variable air_interface air_interface = test.findtext('air_interface') if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): @@ -3329,6 +300,32 @@ def GetParametersFromXML(action): else: ldpc.forced_workspace_cleanup=False + elif action == 'Initialize_MME': + string_field = test.findtext('option') + if (string_field is not None): + EPC.mmeConfFile = string_field + + elif action == 'Deploy_EPC': + string_field = test.findtext('parameters') + if (string_field is not None): + EPC.yamlPath = string_field + + elif action == 'Deploy_Object' or action == 'Undeploy_Object': + eNB_instance=test.findtext('eNB_instance') + if (eNB_instance is None): + CONTAINERS.eNB_instance=0 + else: + CONTAINERS.eNB_instance=int(eNB_instance) + eNB_serverId=test.findtext('eNB_serverId') + if (eNB_serverId is None): + CONTAINERS.eNB_serverId[CONTAINERS.eNB_instance]='0' + else: + CONTAINERS.eNB_serverId[CONTAINERS.eNB_instance]=eNB_serverId + string_field = test.findtext('yaml_path') + if (string_field is not None): + CONTAINERS.yamlPath[CONTAINERS.eNB_instance] = string_field + + else: # ie action == 'Run_PhySim': ldpc.runargs = test.findtext('physim_run_args') @@ -3374,17 +371,13 @@ with open(yaml_file,'r') as f: mode = '' -CiTestObj = OaiCiTest() +CiTestObj = cls_oaicitest.OaiCiTest() SSH = sshconnection.SSHConnection() EPC = epc.EPCManagement() RAN = ran.RANManagement() HTML = html.HTMLManagement() - -EPC.htmlObj=HTML -RAN.htmlObj=HTML -RAN.epcObj=EPC - +CONTAINERS = cls_containerize.Containerize() ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build @@ -3395,24 +388,17 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b #----------------------------------------------------------- import args_parse -py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,HELP) +py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,CONTAINERS,HELP) #----------------------------------------------------------- -# TEMPORARY params management +# TEMPORARY params management (UNUSED) #----------------------------------------------------------- #temporary solution for testing: if py_param_file_present == True: AssignParams(py_params) -#for debug -#print(RAN.__dict__) -#print(CiTestObj.__dict__) -#print(HTML.__dict__) -#print(ldpc.__dict__) -#for debug - #----------------------------------------------------------- # COTS UE instanciation @@ -3423,7 +409,7 @@ COTS_UE=cls_cots_ue.CotsUe(CiTestObj.ADBIPAddress, CiTestObj.ADBUserName,CiTestO #----------------------------------------------------------- -# XML class (action) analysis +# mode amd XML class (action) analysis #----------------------------------------------------------- cwd = os.getcwd() @@ -3431,42 +417,42 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - RAN.eNB_serverId='0' RAN.eNB_instance=0 + RAN.eNB_serverId[0]='0' RAN.eNBSourceCodePath='/tmp/' - RAN.TerminateeNB() + RAN.TerminateeNB(HTML, EPC) elif re.match('^TerminateUE$', mode, re.IGNORECASE): if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') signal.signal(signal.SIGUSR1, receive_signal) - CiTestObj.TerminateUE() + CiTestObj.TerminateUE(HTML,COTS_UE) elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') signal.signal(signal.SIGUSR1, receive_signal) - CiTestObj.TerminateOAIUE() + CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC) elif re.match('^TerminateHSS$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - EPC.TerminateHSS() + EPC.TerminateHSS(HTML) elif re.match('^TerminateMME$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - EPC.TerminateMME() + EPC.TerminateMME(HTML) elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath== '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - EPC.TerminateSPGW() + EPC.TerminateSPGW(HTML) elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): if (RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - CiTestObj.LogCollectBuild() + CiTestObj.LogCollectBuild(RAN) elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '': HELP.GenericHelp(CONST.Version) @@ -3491,12 +477,12 @@ elif re.match('^LogCollectPing$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - CiTestObj.LogCollectPing() + CiTestObj.LogCollectPing(EPC) elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - CiTestObj.LogCollectIperf() + CiTestObj.LogCollectIperf(EPC) elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE): if CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '': HELP.GenericHelp(CONST.Version) @@ -3538,10 +524,13 @@ elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): logging.debug('\u001B[1m Creating HTML footer \u001B[0m') logging.debug('\u001B[1m----------------------------------------\u001B[0m') - CiTestObj.RetrieveSystemVersion('eNB') - CiTestObj.RetrieveSystemVersion('UE') + CiTestObj.RetrieveSystemVersion('eNB',HTML,RAN) + CiTestObj.RetrieveSystemVersion('UE',HTML,RAN) HTML.CreateHtmlFooter(CiTestObj.finalStatus) elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): + logging.debug('\u001B[1m----------------------------------------\u001B[0m') + logging.debug('\u001B[1m Starting Scenario: ' + CiTestObj.testXMLfiles[0] + '\u001B[0m') + logging.debug('\u001B[1m----------------------------------------\u001B[0m') if re.match('^TesteNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': HELP.GenericHelp(CONST.Version) @@ -3577,7 +566,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) repeatCount = xmlRoot.findtext('repeatCount',default='1') + testStability = xmlRoot.findtext('TestUnstable',default='False') CiTestObj.repeatCounts.append(int(repeatCount)) + if testStability == 'True': + CiTestObj.testUnstable = True + HTML.testUnstable = True + CiTestObj.testMinStableId = xmlRoot.findtext('TestMinId',default='999999') + HTML.testMinStableId = CiTestObj.testMinStableId + logging.debug('Test is tagged as Unstable -- starting from TestID ' + str(CiTestObj.testMinStableId)) all_tests=xmlRoot.findall('testCase') exclusion_tests=exclusion_tests.split() @@ -3604,7 +600,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re logging.debug('ERROR: requested test is invalidly formatted: ' + test) sys.exit(1) if (EPC.IPAddress != '') and (EPC.IPAddress != 'none'): - CiTestObj.CheckFlexranCtrlInstallation() + CiTestObj.CheckFlexranCtrlInstallation(RAN,EPC,CONTAINERS) EPC.SetMmeIPAddress() #get the list of tests to be done @@ -3658,89 +654,110 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re if (CiTestObj.ADBIPAddress != 'none'): #in these cases, having no devices is critical, GetAllUEDevices function has to manage it as a critical error, reason why terminate_ue_flag is set to True terminate_ue_flag = True - CiTestObj.GetAllUEDevices(terminate_ue_flag) + # Now we stop properly the test-suite --> clean reporting + status = CiTestObj.GetAllUEDevices(terminate_ue_flag) + if not status: + RAN.prematureExit = True + break if action == 'Build_eNB': - RAN.BuildeNB() + RAN.BuildeNB(HTML) elif action == 'WaitEndBuild_eNB': - RAN.WaitBuildeNBisFinished() + RAN.WaitBuildeNBisFinished(HTML) elif action == 'Initialize_eNB': check_eNB = False check_OAI_UE = False - RAN.pStatus=CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE) - - RAN.InitializeeNB() + RAN.pStatus=CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE,RAN,EPC) + RAN.InitializeeNB(HTML, EPC) elif action == 'Terminate_eNB': - RAN.TerminateeNB() + RAN.TerminateeNB(HTML, EPC) elif action == 'Initialize_UE': - CiTestObj.InitializeUE() + CiTestObj.InitializeUE(HTML,COTS_UE) elif action == 'Terminate_UE': - CiTestObj.TerminateUE() + CiTestObj.TerminateUE(HTML,COTS_UE) elif action == 'Attach_UE': - CiTestObj.AttachUE() + CiTestObj.AttachUE(HTML,RAN,EPC,COTS_UE) elif action == 'Detach_UE': - CiTestObj.DetachUE() + CiTestObj.DetachUE(HTML,RAN,EPC,COTS_UE) elif action == 'DataDisable_UE': - CiTestObj.DataDisableUE() + CiTestObj.DataDisableUE(HTML) elif action == 'DataEnable_UE': - CiTestObj.DataEnableUE() + CiTestObj.DataEnableUE(HTML) elif action == 'CheckStatusUE': - CiTestObj.CheckStatusUE() + CiTestObj.CheckStatusUE(HTML,RAN,EPC,COTS_UE) elif action == 'Build_OAI_UE': - CiTestObj.BuildOAIUE() + CiTestObj.BuildOAIUE(HTML) elif action == 'Initialize_OAI_UE': - CiTestObj.InitializeOAIUE() + CiTestObj.InitializeOAIUE(HTML,RAN,EPC,COTS_UE) elif action == 'Terminate_OAI_UE': - CiTestObj.TerminateOAIUE() + CiTestObj.TerminateOAIUE(HTML,RAN,COTS_UE,EPC) elif action == 'Initialize_CatM_module': - CiTestObj.InitializeCatM() + CiTestObj.InitializeCatM(HTML) elif action == 'Terminate_CatM_module': - CiTestObj.TerminateCatM() + CiTestObj.TerminateCatM(HTML) elif action == 'Attach_CatM_module': - CiTestObj.AttachCatM() + CiTestObj.AttachCatM(HTML,RAN,COTS_UE,EPC) elif action == 'Detach_CatM_module': - CiTestObj.TerminateCatM() + CiTestObj.TerminateCatM(HTML) elif action == 'Ping_CatM_module': - CiTestObj.PingCatM() + CiTestObj.PingCatM(HTML,RAN,EPC,COTS_UE,EPC) elif action == 'Ping': - CiTestObj.Ping() + CiTestObj.Ping(HTML,RAN,EPC,COTS_UE) elif action == 'Iperf': - CiTestObj.Iperf() + CiTestObj.Iperf(HTML,RAN,EPC,COTS_UE) elif action == 'Reboot_UE': - CiTestObj.RebootUE() + CiTestObj.RebootUE(HTML,RAN,EPC) elif action == 'Initialize_HSS': - EPC.InitializeHSS() + EPC.InitializeHSS(HTML) elif action == 'Terminate_HSS': - EPC.TerminateHSS() + EPC.TerminateHSS(HTML) elif action == 'Initialize_MME': - EPC.InitializeMME() + EPC.InitializeMME(HTML) elif action == 'Terminate_MME': - EPC.TerminateMME() + EPC.TerminateMME(HTML) elif action == 'Initialize_SPGW': - EPC.InitializeSPGW() + EPC.InitializeSPGW(HTML) elif action == 'Terminate_SPGW': - EPC.TerminateSPGW() + EPC.TerminateSPGW(HTML) + elif action == 'Deploy_EPC': + EPC.DeployEpc(HTML) + elif action == 'Undeploy_EPC': + EPC.UndeployEpc(HTML) elif action == 'Initialize_FlexranCtrl': - CiTestObj.InitializeFlexranCtrl() + CiTestObj.InitializeFlexranCtrl(HTML,RAN,EPC) elif action == 'Terminate_FlexranCtrl': - CiTestObj.TerminateFlexranCtrl() + CiTestObj.TerminateFlexranCtrl(HTML,RAN,EPC) elif action == 'IdleSleep': - CiTestObj.IdleSleep() + CiTestObj.IdleSleep(HTML) elif action == 'Perform_X2_Handover': - CiTestObj.Perform_X2_Handover() + CiTestObj.Perform_X2_Handover(HTML,RAN,EPC) elif action == 'Build_PhySim': HTML=ldpc.Build_PhySim(HTML,CONST) if ldpc.exitStatus==1:sys.exit() elif action == 'Run_PhySim': HTML=ldpc.Run_PhySim(HTML,CONST,id) + elif action == 'Build_Image': + CONTAINERS.BuildImage(HTML) + elif action == 'Deploy_Object': + CONTAINERS.DeployObject(HTML, EPC) + elif action == 'Undeploy_Object': + CONTAINERS.UndeployObject(HTML, RAN) else: sys.exit('Invalid class (action) from xml') + if not RAN.prematureExit: + if CiTestObj.testCase_id == CiTestObj.testMinStableId: + logging.debug('Scenario has reached minimal stability point') + CiTestObj.testStabilityPointReached = True + HTML.testStabilityPointReached = True CiTestObj.FailReportCnt += 1 if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.prematureExit: - logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') + logging.debug('Scenario failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') HTML.CreateHtmlTabFooter(False) - sys.exit('Failed Scenario') + if CiTestObj.testUnstable and (CiTestObj.testStabilityPointReached or CiTestObj.testMinStableId == '999999'): + logging.debug('Scenario has reached minimal stability point -- Not a Failure') + else: + sys.exit('Failed Scenario') else: - logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)') + logging.info('Scenario passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)') HTML.CreateHtmlTabFooter(True) elif re.match('^LoadParams$', mode, re.IGNORECASE): pass diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index d5906e9567..774d7f19c6 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -42,10 +42,8 @@ from multiprocessing import Process, Lock, SimpleQueue # OAI Testing modules #----------------------------------------------------------- import sshconnection as SSH -import epc import helpreadme as HELP import constants as CONST -import html #----------------------------------------------------------- # Class Declaration @@ -77,19 +75,20 @@ class RANManagement(): self.backgroundBuildTestId = ['', '', ''] self.Build_eNB_forced_workspace_cleanup = False self.Initialize_eNB_args = '' + self.imageKind = '' self.air_interface = ['', '', ''] #changed from 'lte' to '' may lead to side effects in main self.eNB_instance = 0 - self.eNB_serverId = '' + self.eNB_serverId = ['', '', ''] self.eNBLogFiles = ['', '', ''] self.eNBOptions = ['', '', ''] self.eNBmbmsEnables = [False, False, False] self.eNBstatuses = [-1, -1, -1] self.flexranCtrlInstalled = False self.flexranCtrlStarted = False + self.flexranCtrlDeployed = False + self.flexranCtrlIpAddress = '' self.testCase_id = '' self.epcPcapFile = '' - self.htmlObj = None - self.epcObj = None self.runtime_stats= '' @@ -98,21 +97,21 @@ class RANManagement(): # RAN management functions #----------------------------------------------------------- - def BuildeNB(self): + def BuildeNB(self, HTML): if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - if self.eNB_serverId == '0': + if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress lUserName = self.eNBUserName lPassWord = self.eNBPassword lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': + elif self.eNB_serverId[self.eNB_instance] == '1': lIpAddr = self.eNB1IPAddress lUserName = self.eNB1UserName lPassWord = self.eNB1Password lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': + elif self.eNB_serverId[self.eNB_instance] == '2': lIpAddr = self.eNB2IPAddress lUserName = self.eNB2UserName lPassWord = self.eNB2Password @@ -120,6 +119,7 @@ class RANManagement(): if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + logging.debug('Building on server: ' + lIpAddr) mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) @@ -133,14 +133,11 @@ class RANManagement(): self.air_interface[self.eNB_instance] = 'nr-softmodem' else: self.air_interface[self.eNB_instance] = 'lte-softmodem' - + # Worakround for some servers, we need to erase completely the workspace if self.Build_eNB_forced_workspace_cleanup: mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) - if self.htmlObj is not None: - self.testCase_id = self.htmlObj.testCase_id - else: - self.testCase_id = '000000' + self.testCase_id = HTML.testCase_id # on RedHat/CentOS .git extension is mandatory result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: @@ -181,8 +178,7 @@ class RANManagement(): mismatch = True if not mismatch: mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) return mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) @@ -209,26 +205,25 @@ class RANManagement(): mySSH.command('echo ' + lPassWord + ' | sudo -S ls', '\$', 5) mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-build.sh' + ' > ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ' + ' 2>&1 &', lUserName, 5) mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) self.backgroundBuildTestId[int(self.eNB_instance)] = self.testCase_id return mySSH.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee compile_oai_enb.log', 'Bypassing the Tests|build have failed', 1500) mySSH.close() - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id) + self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.testCase_id, HTML) - def WaitBuildeNBisFinished(self): - if self.eNB_serverId == '0': + def WaitBuildeNBisFinished(self, HTML): + if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress lUserName = self.eNBUserName lPassWord = self.eNBPassword lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': + elif self.eNB_serverId[self.eNB_instance] == '1': lIpAddr = self.eNB1IPAddress lUserName = self.eNB1UserName lPassWord = self.eNB1Password lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': + elif self.eNB_serverId[self.eNB_instance] == '2': lIpAddr = self.eNB2IPAddress lUserName = self.eNB2UserName lPassWord = self.eNB2Password @@ -236,6 +231,7 @@ class RANManagement(): if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + logging.debug('Waiting for end of build on server: ' + lIpAddr) mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) count = 40 @@ -249,11 +245,10 @@ class RANManagement(): count -= 1 time.sleep(30) mySSH.close() - self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)]) + self.checkBuildeNB(lIpAddr, lUserName, lPassWord, lSourcePath, self.backgroundBuildTestId[int(self.eNB_instance)], HTML) - def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId): - if self.htmlObj is not None: - self.htmlObj.testCase_id=testcaseId + def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId, HTML): + HTML.testCase_id=testcaseId mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) @@ -284,7 +279,7 @@ class RANManagement(): mySSH.command('mkdir -p build_log_' + testcaseId, '\$', 5) mySSH.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5) mySSH.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5) - if self.eNB_serverId != '0': + if self.eNB_serverId[self.eNB_instance] != '0': mySSH.command('cd cmake_targets', '\$', 5) mySSH.command('if [ -e tmp_build' + testcaseId + '.zip ]; then rm -f tmp_build' + testcaseId + '.zip; fi', '\$', 5) mySSH.command('zip -r -qq tmp_build' + testcaseId + '.zip build_log_' + testcaseId, '\$', 5) @@ -307,27 +302,25 @@ class RANManagement(): #generate logging info depending on buildStatus and air interface if buildStatus: logging.info('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Pass\u001B[0m') - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) else: logging.error('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Failed\u001B[0m') - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK) - self.htmlObj.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTabFooter(False) sys.exit(1) - def InitializeeNB(self): - if self.eNB_serverId == '0': + def InitializeeNB(self, HTML, EPC): + if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress lUserName = self.eNBUserName lPassWord = self.eNBPassword lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': + elif self.eNB_serverId[self.eNB_instance] == '1': lIpAddr = self.eNB1IPAddress lUserName = self.eNB1UserName lPassWord = self.eNB1Password lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': + elif self.eNB_serverId[self.eNB_instance] == '2': lIpAddr = self.eNB2IPAddress lUserName = self.eNB2UserName lPassWord = self.eNB2Password @@ -335,24 +328,21 @@ class RANManagement(): if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + logging.debug('Starting eNB/gNB on server: ' + lIpAddr) - if self.htmlObj is not None: - self.testCase_id = self.htmlObj.testCase_id - else: - self.testCase_id = '000000' + self.testCase_id = HTML.testCase_id mySSH = SSH.SSHConnection() if (self.pStatus < 0): - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus) - self.htmlObj.CreateHtmlTabFooter(False) + HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus) + HTML.CreateHtmlTabFooter(False) sys.exit(1) # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if (result is not None) and (self.epcObj is not None): - localEpcIpAddr = self.epcObj.IPAddress - localEpcUserName = self.epcObj.UserName - localEpcPassword = self.epcObj.Password + if (result is not None): + localEpcIpAddr = EPC.IPAddress + localEpcUserName = EPC.UserName + localEpcPassword = EPC.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) mySSH.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5) result = re.search('interfaceToUse=(?P[a-zA-Z0-9\-\_]+)done', mySSH.getBefore()) @@ -400,17 +390,17 @@ class RANManagement(): mySSH.command('echo ' + lPassWord + ' | sudo -S uhd_find_devices', '\$', 60) # Make a copy and adapt to EPC / eNB IP addresses mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) - if self.epcObj is not None: - localMmeIpAddr = self.epcObj.MmeIPAddress - mySSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/\' ' + ci_full_config_file, '\$', 2); + localMmeIpAddr = EPC.MmeIPAddress + mySSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_GNB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_FR1_CTL_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); - if self.flexranCtrlInstalled and self.flexranCtrlStarted: + if (self.flexranCtrlInstalled and self.flexranCtrlStarted) or self.flexranCtrlDeployed: mySSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2); + mySSH.command('sed -i -e \'s/CI_FLEXRAN_CTL_IP_ADDR/' + self.flexranCtrlIpAddress + '/\' ' + ci_full_config_file, '\$', 2); else: mySSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "no";/\' ' + ci_full_config_file, '\$', 2); self.eNBmbmsEnables[int(self.eNB_instance)] = False @@ -427,7 +417,7 @@ class RANManagement(): # Launch eNB with the modified config file mySSH.command('source oaienv', '\$', 5) mySSH.command('cd cmake_targets', '\$', 5) - if self.air_interface == 'nr': + if self.air_interface[self.eNB_instance] == 'nr-softmodem': mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5) mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5) # NOTE: WE SHALL do a check if the executable is present (in case build went wrong) @@ -452,14 +442,13 @@ class RANManagement(): mySSH.close() doLoop = False logging.error('\u001B[1;37;41m eNB/gNB/ocp-eNB logging system did not show got sync! \u001B[0m') - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK) # In case of T tracer recording, we need to kill tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if (result is not None) and (self.epcObj is not None): - localEpcIpAddr = self.epcObj.IPAddress - localEpcUserName = self.epcObj.UserName - localEpcPassword = self.epcObj.Password + if (result is not None): + localEpcIpAddr = EPC.IPAddress + localEpcUserName = EPC.UserName + localEpcPassword = EPC.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) logging.debug('\u001B[1m Stopping tshark \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) @@ -507,11 +496,10 @@ class RANManagement(): else: logging.error('\u001B[1m oaitun_enm1 interface is either NOT mounted or NOT configured\u001B[0m') if enbDidSync: - self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId) + self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId[self.eNB_instance]) mySSH.close() - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK) logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m') def CheckeNBProcess(self, status_queue): @@ -546,18 +534,18 @@ class RANManagement(): except: os.kill(os.getppid(),signal.SIGUSR1) - def TerminateeNB(self): - if self.eNB_serverId == '0': + def TerminateeNB(self, HTML, EPC): + if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress lUserName = self.eNBUserName lPassWord = self.eNBPassword lSourcePath = self.eNBSourceCodePath - elif self.eNB_serverId == '1': + elif self.eNB_serverId[self.eNB_instance] == '1': lIpAddr = self.eNB1IPAddress lUserName = self.eNB1UserName lPassWord = self.eNB1Password lSourcePath = self.eNB1SourceCodePath - elif self.eNB_serverId == '2': + elif self.eNB_serverId[self.eNB_instance] == '2': lIpAddr = self.eNB2IPAddress lUserName = self.eNB2UserName lPassWord = self.eNB2Password @@ -565,6 +553,7 @@ class RANManagement(): if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') + logging.debug('Stopping eNB/gNB on server: ' + lIpAddr) mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) @@ -586,10 +575,10 @@ class RANManagement(): mySSH.close() # If tracer options is on, stopping tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if (result is not None) and (self.epcObj is not None): - localEpcIpAddr = self.epcObj.IPAddress - localEpcUserName = self.epcObj.UserName - localEpcPassword = self.epcObj.Password + if (result is not None): + localEpcIpAddr = EPC.IPAddress + localEpcUserName = EPC.UserName + localEpcPassword = EPC.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) logging.debug('\u001B[1m Stopping tshark \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) @@ -613,9 +602,8 @@ class RANManagement(): mySSH.close() mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.') logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_eNB(extracted_log_file) - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + logStatus = self.AnalyzeLogFile_eNB(extracted_log_file, HTML) + HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) self.eNBLogFiles[int(self.eNB_instance)] = '' else: analyzeFile = False @@ -627,27 +615,23 @@ class RANManagement(): copyin_res = mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + fileToAnalyze, '.') if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m') - if self.htmlObj is not None: - self.htmlObj.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' - self.htmlObj.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) + HTML.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' + HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) self.eNBmbmsEnables[int(self.eNB_instance)] = False return - if self.eNB_serverId != '0': + if self.eNB_serverId[self.eNB_instance] != '0': mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/') logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + fileToAnalyze) - logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze) + logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze, HTML) if (logStatus < 0): - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow('N/A', 'KO', logStatus) + HTML.CreateHtmlTestRow('N/A', 'KO', logStatus) self.preamtureExit = True self.eNBmbmsEnables[int(self.eNB_instance)] = False return else: - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) else: - if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK) self.eNBmbmsEnables[int(self.eNB_instance)] = False self.eNBstatuses[int(self.eNB_instance)] = -1 @@ -661,7 +645,7 @@ class RANManagement(): mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5) mySSH.close() - def AnalyzeLogFile_eNB(self, eNBlogFile): + def AnalyzeLogFile_eNB(self, eNBlogFile, HTML): if (not os.path.isfile('./' + eNBlogFile)): return -1 enb_log_file = open('./' + eNBlogFile, 'r') @@ -705,6 +689,15 @@ class RANManagement(): systemTime = '' maxPhyMemUsage = '' nbContextSwitches = '' + #NSA FR1 check + NSA_RAPROC_PUSCH_check = 0 + #dlsch and ulsch statistics (dictionary) + dlsch_ulsch_stats = {} + #count "L1 thread not ready" msg + L1_thread_not_ready_cnt = 0 + #count "problem receiving samples" msg + pb_receiving_samples_cnt = 0 + for line in enb_log_file.readlines(): # Runtime statistics result = re.search('Run time:' ,str(line)) @@ -855,12 +848,36 @@ class RANManagement(): result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line)) if result is not None: mbmsRequestMsg += 1 + #FR1 NSA test : add new markers to make sure gNB is used + result = re.search('\[gNB [0-9]+\]\[RAPROC\] PUSCH with TC_RNTI [0-9a-fA-F]+ received correctly, adding UE MAC Context UE_id [0-9]+\/RNTI [0-9a-fA-F]+', str(line)) + if result is not None: + NSA_RAPROC_PUSCH_check = 1 + #dlsch and ulsch statistics + #keys below are the markers we are loooking for, loop over this keys list + #everytime these markers are found in the log file, the previous ones are overwritten in the dict + #eventually we record and print only the last occurence + keys = {'dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'} + for k in keys: + result = re.search(k, line) + if result is not None: + #remove 1- all useless char before relevant info (ulsch or dlsch) 2- trailing char + dlsch_ulsch_stats[k]=re.sub(r'^.*\]\s+', r'' , line.rstrip()) + #count "L1 thread not ready" msg + result = re.search('\[PHY\]\s+L1_thread isn\'t ready', str(line)) + if result is not None: + L1_thread_not_ready_cnt += 1 + #count "problem receiving samples" msg + result = re.search('\[PHY\]\s+problem receiving samples', str(line)) + if result is not None: + pb_receiving_samples_cnt += 1 + enb_log_file.close() logging.debug(' File analysis completed') if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): nodeB_prefix = 'e' else: nodeB_prefix = 'g' + if self.air_interface[self.eNB_instance] == 'nr-softmodem': if ulschReceiveOK > 0: statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)' @@ -874,6 +891,34 @@ class RANManagement(): statMsg = nodeB_prefix + 'NB ran with TX Write thread enabled' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') htmleNBFailureMsg += statMsg + '\n' + #FR1 NSA test : add new markers to make sure gNB is used + if NSA_RAPROC_PUSCH_check: + statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : PASS ' + htmlMsg = statMsg+'\n' + else: + statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL ' + htmlMsg = statMsg+'\n' + logging.debug(statMsg) + htmleNBFailureMsg += htmlMsg + #L1 thread not ready log + statMsg = '[PHY] L1 thread is not ready msg count = '+str(L1_thread_not_ready_cnt) + htmlMsg = statMsg+'\n' + logging.debug(statMsg) + htmleNBFailureMsg += htmlMsg + #problem receiving samples log + statMsg = '[PHY] problem receiving samples msg count = '+str(pb_receiving_samples_cnt) + htmlMsg = statMsg+'\n' + logging.debug(statMsg) + htmleNBFailureMsg += htmlMsg + + #ulsch and dlsch statistics + if len(dlsch_ulsch_stats)!=0: #check if dictionary is not empty + statMsg='' + for key in dlsch_ulsch_stats: #for each dictionary key + statMsg += dlsch_ulsch_stats[key] + '\n' + logging.debug(dlsch_ulsch_stats[key]) + htmleNBFailureMsg += statMsg + if uciStatMsgCount > 0: statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -981,8 +1026,7 @@ class RANManagement(): logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') htmleNBFailureMsg += rlcMsg + '\n' global_status = CONST.ENB_PROCESS_REALTIME_ISSUE - if self.htmlObj is not None: - self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg + HTML.htmleNBFailureMsg=htmleNBFailureMsg # Runtime statistics for console output and HTML if runTime != '': logging.debug(runTime) diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 5f5f5caa35..8562f4b2de 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -470,7 +470,7 @@ function report_test { then NB_UE_TUNNEL_UP=`egrep -c "Interface oaitun_ue1 successfully configured" $UE_LOG` else - NB_UE_TUNNEL_UP=`egrep -c "executing ifconfig oaitun_ue1" $UE_LOG` + NB_UE_TUNNEL_UP=`egrep -c "ip link set oaitun_ue1 up" $UE_LOG` fi if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 0 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] then @@ -769,8 +769,8 @@ function report_test { #RA test (--do-ra option) #build log files names - RA_ENB_LOG=$ARCHIVES_LOC/ra_check_${TMODE}_${BW}prb_${CN_CONFIG}_gnb.log - RA_UE_LOG=$ARCHIVES_LOC/ra_check_${TMODE}_${BW}prb_${CN_CONFIG}_ue.log + RA_ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_gnb_ra_test.log + RA_UE_LOG=$ARCHIVES_LOC/${TMODE}_${BW}prb_${CN_CONFIG}_ue_ra_test.log if [ -f $RA_ENB_LOG ] && [ -f $RA_UE_LOG ] then #get rid of full path @@ -781,13 +781,12 @@ function report_test { echo " Check if RA proc succeeded" >> ./test_simulator_results.html #gNB RA check - GNB_RECEIVED=`egrep -c "received correctly" $RA_ENB_LOG` - GNB_CONNECTED=`egrep -c "now 5G connected" $RA_ENB_LOG` + GNB_RECEIVED=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $RA_ENB_LOG` #UE RA check - UE_RA_PROC_OK=`egrep -c "RA procedure succeeded" $RA_UE_LOG` + UE_RA_PROC_OK=`egrep -c "\[RAPROC\] RA procedure succeeded" $RA_UE_LOG` - if [ $GNB_RECEIVED -gt 0 ] && [ $GNB_CONNECTED -gt 0 ] && [ $UE_RA_PROC_OK -gt 0 ] + if [ $GNB_RECEIVED -gt 0 ] && [ $UE_RA_PROC_OK -gt 0 ] then echo " OK" >> ./test_simulator_results.html else @@ -801,12 +800,6 @@ function report_test { else echo "- gNB RA NOT RECEIVED" >> ./test_simulator_results.html fi - if [ $GNB_CONNECTED -gt 0 ] - then - echo "- gNB --> 5G connected" >> ./test_simulator_results.html - else - echo "- gNB NOT 5G CONNECTED" >> ./test_simulator_results.html - fi if [ $UE_RA_PROC_OK -gt 0 ] then echo "- NR UE --> RA procedure succeded" >> ./test_simulator_results.html diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 7f2ce6279d..70eabb7b69 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -281,14 +281,35 @@ function check_ra_result { local LOC_GNB_LOG=$1 local LOC_UE_LOG=$2 - #gNB RA test - echo "Checking gNB Log for RA success" - egrep "received correctly" $1 - egrep "now 5G connected" $1 - - #UE RA test - echo 'Checking UE Log for RA success' - egrep "RA procedure succeeded" $2 + #if log files exist + if [ -f $LOC_GNB_LOG ] && [ -f $LOC_UE_LOG ] + then + + #gNB RA test + #console check + echo "Checking gNB Log for RA success" + egrep "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $1 + #script check + local GNB_COMPLETE=`egrep -c "\[RAPROC\] PUSCH with TC_RNTI (.+) received correctly" $1` + + #UE RA test + #console check + echo 'Checking UE Log for RA success' + egrep "\[RAPROC\] RA procedure succeeded" $2 + #script check + local UE_COMPLETE=`egrep -c "\[RAPROC\] RA procedure succeeded" $2` + + #generate status + if [ $GNB_COMPLETE -eq 0 ] || [ $UE_COMPLETE -eq 0 ] + then + RA_STATUS=-1 + echo "RA test FAILED, could not find the markers" + fi + #case where log files do not exist + else + echo "RA test log files not present" + RA_STATUS=-1 + fi } @@ -1199,6 +1220,8 @@ function start_rf_sim_gnb { 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 "echo \"export RFSIMULATOR=server\"" >> $1 + echo "export RFSIMULATOR=server" >> $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 @@ -1212,9 +1235,9 @@ function start_rf_sim_gnb { then if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option then - echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --phy-test\" > ./my-nr-softmodem-run.sh " >> $1 else #RA test => use --do-ra option - echo "echo \"RFSIMULATOR=server ./nr-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE --log_config.global_log_options level,nocolor --parallel-config PARALLEL_SINGLE_THREAD --noS1 --nokrnmod 1 --rfsim --do-ra\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./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 --rfsim --do-ra\" > ./my-nr-softmodem-run.sh " >> $1 fi fi echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 @@ -1225,6 +1248,7 @@ function start_rf_sim_gnb { 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 ] @@ -1247,7 +1271,9 @@ function start_rf_sim_gnb { GNB_SYNC=1 echo "RF-SIM gNB is sync'ed: waiting for UE(s) to connect" fi - if [ $LOC_S1_CONFIGURATION -eq 0 ] + + # check noS1 config only outside RA test (as it does not support noS1) + if [ $LOC_S1_CONFIGURATION -eq 0 ] && [ $LOC_RA_TEST -eq 0 ] then echo "ifconfig oaitun_enb1 | egrep -c \"inet addr\"" > $1 # Checking oaitun_enb1 interface has now an IP address @@ -1301,6 +1327,8 @@ function start_rf_sim_nr_ue { 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 \"export RFSIMULATOR=${LOC_GNB_VM_IP_ADDR}\"" >> $1 + echo "export RFSIMULATOR=${LOC_GNB_VM_IP_ADDR}" >> $1 echo "echo \"cd /home/ubuntu/tmp/cmake_targets/ran_build/build/\"" >> $1 echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 echo "sudo cp /home/ubuntu/tmp/r*config.raw /home/ubuntu/tmp/cmake_targets/ran_build/build/" >> $1 @@ -1310,9 +1338,9 @@ function start_rf_sim_nr_ue { then if [ $LOC_RA_TEST -eq 0 ] #no RA test => use --phy-test option then - echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-uesoftmodem --nokrnmod 1 --rfsim --phy-test --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 else #RA test => use --do-ra option - echo "echo \"RFSIMULATOR=${LOC_GNB_VM_IP_ADDR} ./nr-uesoftmodem --nokrnmod 1 --rfsim --do-ra --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/ --log_config.global_log_options level,nocolor --noS1\" > ./my-nr-softmodem-run.sh " >> $1 + echo "echo \"./nr-uesoftmodem --rfsim --do-ra --log_config.global_log_options level,nocolor --rrc_config_path /home/ubuntu/tmp/cmake_targets/ran_build/build/\" > ./my-nr-softmodem-run.sh " >> $1 fi fi echo "chmod 775 ./my-nr-softmodem-run.sh" >> $1 @@ -1346,11 +1374,13 @@ function start_rf_sim_nr_ue { 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 + # Checking oaitun_ue1 interface has now an IP address (only outside RA test) + if [ $LOC_RA_TEST -eq 0 ] + then + 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 ] @@ -1359,21 +1389,20 @@ function start_rf_sim_nr_ue { else i=$[$i+1] fi - done - echo "echo \"free -m\"" > $1 - echo "free -m" >> $1 - ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 - rm $1 - if [ $i -lt 50 ] - then + done + echo "echo \"free -m\"" > $1 + echo "free -m" >> $1 + ssh -T -o StrictHostKeyChecking=no ubuntu@$LOC_NR_UE_VM_IP_ADDR < $1 + rm $1 + if [ $i -lt 50 ] + then NR_UE_SYNC=0 echo "RF-SIM NR-UE oaitun_ue1 is DOWN or NOT CONFIGURED" - else + else echo "RF-SIM NR-UE oaitun_ue1 is UP and CONFIGURED" - fi - sleep 10 - - + fi + sleep 10 + fi } @@ -2166,29 +2195,33 @@ function run_test_on_vm { PRB=106 FREQUENCY=3510 - local try_cnt="0" + if [ ! -d $ARCHIVES_LOC ] + then + mkdir --parents $ARCHIVES_LOC + fi + + local try_cnt=0 NR_STATUS=0 - ######### start of loop - while [ $try_cnt -lt 4 ] + ######### start of RA TEST loop + while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI do - #start RA test SYNC_STATUS=0 - PING_STATUS=0 - IPERF_STATUS=0 + RA_STATUS=0 + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_test.log echo "############################################################" echo "${CN_CONFIG} : Starting the gNB" echo "############################################################" - CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log + CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log #last argument = 1 is to enable --do-ra for RA test start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1 echo "############################################################" echo "${CN_CONFIG} : Starting the NR-UE" echo "############################################################" - CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log + CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_test.log #last argument = 1 is to enable --do-ra for RA test start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1 if [ $NR_UE_SYNC -eq 0 ] @@ -2199,11 +2232,10 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC SYNC_STATUS=-1 - try_cnt=$[$try_cnt+1] + try_cnt=$((try_cnt+1)) continue fi - echo "############################################################" echo "${CN_CONFIG} : Terminate gNB/NR-UE simulators" echo "############################################################" @@ -2213,26 +2245,39 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC - - #check RA markers in gNB and NR UE log files echo "############################################################" echo "${CN_CONFIG} : Checking RA on gNB / NR-UE" echo "############################################################" - mv $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_GNB_LOG_FILE - mv $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_NR_UE_LOG_FILE - check_ra_result $ARCHIVES_LOC/ra_check_$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/ra_check_$CURRENT_NR_UE_LOG_FILE - - - #end RA test + # Proper check to be done when RA test is working! + check_ra_result $ARCHIVES_LOC/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC/$CURRENT_NR_UE_LOG_FILE + if [ $RA_STATUS -ne 0 ] + then + echo "RA test NOT OK" + echo "try_cnt = " $try_cnt + try_cnt=$((try_cnt+1)) + else + try_cnt=$((try_cnt+10)) + fi + done + ########### end RA test + + sleep 30 + ######### start of PHY TEST loop + try_cnt=0 + while [ $try_cnt -lt 4 ] + do SYNC_STATUS=0 PING_STATUS=0 IPERF_STATUS=0 + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ue.log + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log + rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_ul*txt echo "############################################################" echo "${CN_CONFIG} : Starting the gNB" @@ -2253,7 +2298,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC SYNC_STATUS=-1 - try_cnt=$[$try_cnt+1] + try_cnt=$((try_cnt+1)) continue fi @@ -2293,7 +2338,7 @@ function run_test_on_vm { terminate_enb_ue_basic_sim $GNB_VM_CMDS $GNB_VM_IP_ADDR 1 scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_GNB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_NR_UE_LOG_FILE $ARCHIVES_LOC - try_cnt=$[$try_cnt+1] + try_cnt=$((try_cnt+1)) continue fi @@ -2319,9 +2364,9 @@ function run_test_on_vm { if [ $IPERF_STATUS -ne 0 ] then echo "UL test not OK" - try_cnt=$[$try_cnt+1] + try_cnt=$((try_cnt+1)) else - try_cnt=$[$try_cnt+10] + try_cnt=$((try_cnt+10)) fi done ######### end of loop @@ -2332,6 +2377,7 @@ function run_test_on_vm { echo "Checking run status" echo "############################################################" + if [ $RA_STATUS -ne 0 ]; then NR_STATUS=-1; fi if [ $SYNC_STATUS -ne 0 ]; then NR_STATUS=-1; fi if [ $PING_STATUS -ne 0 ]; then NR_STATUS=-1; fi if [ $IPERF_STATUS -ne 0 ]; then NR_STATUS=-1; fi diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py index ed0cf5379a..5bfe5da70f 100644 --- a/ci-scripts/sshconnection.py +++ b/ci-scripts/sshconnection.py @@ -52,13 +52,11 @@ class SSHConnection(): self.picocom_closure = True def open(self, ipaddress, username, password): - extraSshOptions = '' count = 0 connect_status = False - if ipaddress == '192.168.18.197': - extraSshOptions = ' -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' while count < 4: - self.ssh = pexpect.spawn('ssh', [username + '@' + ipaddress + extraSshOptions], timeout = 5) + self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=no {}@{}'.format(username,ipaddress)) + self.ssh.timeout = 5 self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) if self.sshresponse == 0: self.ssh.sendline('yes') diff --git a/ci-scripts/tcp_iperf_stats.awk b/ci-scripts/tcp_iperf_stats.awk index 3a00e4555f..b21bf16a2f 100644 --- a/ci-scripts/tcp_iperf_stats.awk +++ b/ci-scripts/tcp_iperf_stats.awk @@ -21,7 +21,11 @@ BEGIN{max=0;min=10000} { if ($0 ~/Mbits/) { - split($0,a,"MBytes") + if ($0 ~/KBytes/) { + split($0,a,"KBytes") + } else { + split($0,a,"MBytes") + } split(a[2],b) if (b[1]>max) { max=b[1] diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index 2c20988851..0e00a2e7d4 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -19,6 +19,8 @@ - Reboot_UE - Initialize_FlexranCtrl - Terminate_FlexranCtrl + - Deploy_EPC + - Undeploy_EPC - Initialize_HSS - Terminate_HSS - Initialize_MME @@ -32,3 +34,6 @@ - Ping_CatM_module - IdleSleep - Perform_X2_Handover + - Build_Image + - Deploy_Object + - Undeploy_Object diff --git a/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml b/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml index 7280a87fb8..d73a1e26e9 100644 --- a/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml +++ b/ci-scripts/xml_files/enb_ue_usrp210_band7_ue_build.xml @@ -32,7 +32,7 @@ Build_OAI_UE Build OAI UE - -w USRP --UE + -w USRP --UE --ninja diff --git a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml index 611492b0bc..cdba0723df 100644 --- a/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band13_test_10mhz_tm1.xml @@ -25,6 +25,7 @@ Test-LTE-M-10MHz-TM1 tasks 1 + True 030201 040102 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml index 09aa0b04a2..5ece10d37e 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm2.xml @@ -26,6 +26,8 @@ Test-05MHz-TM2 tasks 2 + True + 040608 030201 040101 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml index 29699d3b3d..b1d87e598e 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml @@ -24,6 +24,8 @@ test-10-tm1 Test-10MHz-TM1 tasks + True + 040615 030201 040101 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml index f98ed1600a..d75704aceb 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml @@ -25,6 +25,8 @@ Test-20MHz-TM1 tasks 4 + True + 040623 030201 040101 diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml index fd018f7a9c..a6530a920c 100644 --- a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1_default_scheduler.xml @@ -24,6 +24,8 @@ test-20-tm1-defSched Test-20MHz-TM1-default-scheduler tasks + True + 040522 030201 040101 diff --git a/ci-scripts/xml_files/fr1_epc_start_verizon.xml b/ci-scripts/xml_files/fr1_epc_start_verizon.xml new file mode 100644 index 0000000000..19f5c03985 --- /dev/null +++ b/ci-scripts/xml_files/fr1_epc_start_verizon.xml @@ -0,0 +1,49 @@ + + + epc-start-tab + EPC-Start + log-in + + 000100 000101 000102 + + + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/fr1_image_build.xml b/ci-scripts/xml_files/fr1_image_build.xml new file mode 100644 index 0000000000..9dd386b646 --- /dev/null +++ b/ci-scripts/xml_files/fr1_image_build.xml @@ -0,0 +1,40 @@ + + + build-tab + Build + wrench + + 000001 + + + + + Build_Image + Build eNB Image + all + 0 + 0 + + + diff --git a/ci-scripts/xml_files/fr1_oai_cn_deploy.xml b/ci-scripts/xml_files/fr1_oai_cn_deploy.xml new file mode 100644 index 0000000000..919def7aa3 --- /dev/null +++ b/ci-scripts/xml_files/fr1_oai_cn_deploy.xml @@ -0,0 +1,39 @@ + + + epc-deploy-tab + EPC-Deploy + log-in + + 000100 + + + + + + Deploy_EPC + Deploy all EPC containers + yaml_files/fr1_epc_tim + + + diff --git a/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml b/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml new file mode 100644 index 0000000000..76192efea1 --- /dev/null +++ b/ci-scripts/xml_files/fr1_oai_cn_undeploy.xml @@ -0,0 +1,38 @@ + + + epc-undeploy-tab + EPC-Undeploy + log-out + + 000200 + + + + + + Undeploy_EPC + Undeploy all EPC containers + + + diff --git a/ci-scripts/xml_files/fr1_ran_ue_base.xml b/ci-scripts/xml_files/fr1_ran_ue_base.xml new file mode 100644 index 0000000000..847967f81e --- /dev/null +++ b/ci-scripts/xml_files/fr1_ran_ue_base.xml @@ -0,0 +1,150 @@ + + + TEST-FR1-TM1 + FR1 + tasks + + 010000 + 030000 + 040000 + 010001 + 000001 + 050000 + 050001 + 050002 + 050002 + 000001 + 060000 + 060001 + 000001 + 010002 + 000001 + 070001 + 070000 + 010003 + + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + + Initialize_eNB + Initialize eNB + -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf + 0 + 0 + lte + + + + + Initialize_eNB + Initialize gNB + -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E + 1 + 1 + nr + + + + IdleSleep + Sleep + 20 + + + + Ping + Ping: 20pings in 20sec + -c 20 + 50 + + + + Ping + Ping: 5pings in 1sec + -c 5 -i 0.2 + 50 + + + + Ping + Ping: 100pings in 20sec + -c 100 -i 0.2 + 50 + + + + + Iperf + iperf (DL/1Mbps/UDP)(30 sec)(single-ue profile) + -u -b 1M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (UL/1Mbps/UDP)(30 sec)(single-ue profile) + -u -b 1M -t 30 -i 1 -R + 50 + single-ue + + + + Terminate_eNB + Terminate eNB + 0 + 0 + lte + + + + Terminate_eNB + Terminate gNB + 1 + 1 + nr + + + + diff --git a/ci-scripts/xml_files/fr1_ran_ue_proc.xml b/ci-scripts/xml_files/fr1_ran_ue_iperf.xml similarity index 79% rename from ci-scripts/xml_files/fr1_ran_ue_proc.xml rename to ci-scripts/xml_files/fr1_ran_ue_iperf.xml index e86a36d2db..8ead3afc62 100644 --- a/ci-scripts/xml_files/fr1_ran_ue_proc.xml +++ b/ci-scripts/xml_files/fr1_ran_ue_iperf.xml @@ -31,10 +31,14 @@ 010001 000001 050000 - 050001 + 000001 + 060000 + 060001 + 000001 + 010002 + 000001 070001 070000 - 010002 010003 @@ -89,14 +93,24 @@ Ping Ping: 20pings in 20sec -c 20 - 0 + 50 - - Ping - Ping: 5pings in 1sec - -c 5 -i 0.2 - 0 + + + Iperf + iperf (DL/2.5Mbps/UDP)(60 sec)(single-ue profile) + -u -b 2.5M -t 60 -i 1 + 50 + single-ue + + + + Iperf + iperf (UL/1.5Mbps/UDP)(60 sec)(single-ue profile) + -u -b 1.5M -t 60 -i 1 -R + 50 + single-ue @@ -104,6 +118,7 @@ Terminate eNB 0 0 + lte @@ -111,6 +126,7 @@ Terminate gNB 1 1 + nr diff --git a/ci-scripts/xml_files/fr1_usrp210_band7_deploy_test_05mhz_tm1.xml b/ci-scripts/xml_files/fr1_usrp210_band7_deploy_test_05mhz_tm1.xml new file mode 100644 index 0000000000..3d04fdeb29 --- /dev/null +++ b/ci-scripts/xml_files/fr1_usrp210_band7_deploy_test_05mhz_tm1.xml @@ -0,0 +1,133 @@ + + + test-deploy-enb-mono + Test-Deploy-eNB-Mono + tasks + 1 + + 040101 + 030101 000020 040301 000021 040501 040601 040611 040641 040651 040401 040201 030201 + + + + + IdleSleep + Waiting for 60 seconds + 60 + + + + IdleSleep + Waiting for 10 seconds + 10 + + + + CheckStatusUE + Check UE(s) status before attachment + 0 + + + + CheckStatusUE + Check UE(s) status after attachment + 1 + + + + Deploy_Object + Deploy eNB (FDD/Band7/5MHz) in a container + ci-scripts/yaml_files/fr1_enb_mono_fdd_tim + 0 + 0 + + + + Undeploy_Object + Undeploy eNB + ci-scripts/yaml_files/fr1_enb_mono_fdd_tim + 0 + 0 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec) + -u -b 15M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec) + -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/7.5Mbps/UDP)(30 sec) + -u -b 7.5M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec) + -t 30 -i 1 -R + 50 + single-ue + + + diff --git a/ci-scripts/xml_files/fr1_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/fr1_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000..ea25d5b694 --- /dev/null +++ b/ci-scripts/xml_files/fr1_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,151 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + + 030201 + 040101 + 030101 040301 000001 040501 040603 040401 030201 + + + + + IdleSleep + Sleep + 5 + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --eNBs.[0].plmn_list.[0].mcc 311 --eNBs.[0].plmn_list.[0].mnc 480 --eNBs.[0].plmn_list.[0].mnc_length 3 --eNBs.[0].component_carriers.[0].Nid_cell 10 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) + -u -b 15M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 15M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) + -u -b 9M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml index a344cb6a7f..b1e9697be2 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path . + --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 50 --rrc_config_path . --dlsch-parallel 4 NR diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml index 9e5e0a2bac..2c44ead8ea 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path . + --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --rrc_config_path . --dlsch-parallel 4 NR diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml index 8276294e9a..9224c67fe7 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml @@ -25,6 +25,8 @@ Test-10MHz tasks 2 + True + 040612 030201 040101 diff --git a/ci-scripts/xml_files/ue_band20_build.xml b/ci-scripts/xml_files/ue_band20_build.xml index 9ca1a2b234..d867929630 100644 --- a/ci-scripts/xml_files/ue_band20_build.xml +++ b/ci-scripts/xml_files/ue_band20_build.xml @@ -32,7 +32,7 @@ Build_OAI_UE Build OAI UE - -w USRP --UE + -w USRP --UE --ninja diff --git a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml index c43be75a87..7256c985c5 100644 --- a/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/x2ho_enb_usrp210_band13_test_05mhz_tm1.xml @@ -26,6 +26,7 @@ Test-X2-HO-FDD-05MHz-TM1 tasks 2 + True 030201 030202 040101 diff --git a/ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml b/ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml new file mode 100644 index 0000000000..2df277d78b --- /dev/null +++ b/ci-scripts/yaml_files/fr1_enb_mono_fdd_tim/docker-compose.yml @@ -0,0 +1,49 @@ +version: '3.8' + +services: + enb_mono_fdd: + image: oai-enb:latest + privileged: true + container_name: prod-enb-mono-fdd + environment: + USE_FDD_MONO: 'yes' + USE_B2XX: 'yes' + ENB_NAME: eNB-in-docker + MCC: '222' + MNC: '01' + MNC_LENGTH: 2 + TAC: 1 + UTRA_BAND_ID: 7 + DL_FREQUENCY_IN_MHZ: 2680 + UL_FREQUENCY_OFFSET_IN_MHZ: 120 + NID_CELL: 10 + NB_PRB: 25 + MME_S1C_IP_ADDRESS: CI_MME_IP_ADDR + ENB_S1C_IF_NAME: eth0 + ENB_S1C_IP_ADDRESS: 192.168.61.30 + ENB_S1U_IF_NAME: eth0 + ENB_S1U_IP_ADDRESS: 192.168.61.30 + ENB_X2_IP_ADDRESS: 192.168.61.30 + FLEXRAN_ENABLED: 'no' + FLEXRAN_INTERFACE_NAME: eth0 + FLEXRAN_IPV4_ADDRESS: CI_FLEXRAN_CTL_IP_ADDR + USE_ADDITIONAL_OPTIONS: '--RUs.[0].max_rxgain 115 --RUs.[0].max_pdschReferenceSignalPower -27 --eNBs.[0].component_carriers.[0].pucch_p0_Nominal -96' + volumes: + - /dev:/dev + networks: + public_net: + ipv4_address: 192.168.61.30 + healthcheck: + # pgrep does NOT work + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + +networks: + public_net: + name: prod-oai-public-net + ipam: + config: + - subnet: 192.168.61.0/26 + diff --git a/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml b/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml new file mode 100644 index 0000000000..28ae154838 --- /dev/null +++ b/ci-scripts/yaml_files/fr1_epc_tim/docker-compose.yml @@ -0,0 +1,203 @@ +version: '3.8' + +services: + cassandra: + image: cassandra:2.1 + container_name: prod-cassandra + networks: + private_net: + ipv4_address: 192.168.68.2 + environment: + CASSANDRA_CLUSTER_NAME: "OAI HSS Cluster" + CASSANDRA_ENDPOINT_SNITCH: GossipingPropertyFileSnitch + healthcheck: + test: /bin/bash -c "nodetool status" + interval: 10s + timeout: 5s + retries: 5 + + db_init: + image: cassandra:2.1 + container_name: prod-db-init + depends_on: [cassandra] + deploy: + restart_policy: + condition: on-failure + max_attempts: 10 + networks: + private_net: + ipv4_address: 192.168.68.4 + volumes: + - ./oai_db.cql:/home/oai_db.cql + entrypoint: /bin/bash -c "cqlsh --file /home/oai_db.cql 192.168.68.2 && echo 'OK'" + + oai_hss: + image: oai-hss:production + container_name: prod-oai-hss + privileged: true + depends_on: [cassandra] + networks: + private_net: + ipv4_address: 192.168.68.3 + public_net: + ipv4_address: 192.168.61.2 + environment: + REALM: openairinterface.org + HSS_FQDN: hss.openairinterface.org + PREFIX: /openair-hss/etc + cassandra_Server_IP: 192.168.68.2 + OP_KEY: 1006020f0a478bf6b699f15c062e42b3 + LTE_K: fec86ba6eb707ed08905757b1bb44b8f + APN1: oai.ipv4 + APN2: internet + FIRST_IMSI: 222010100001120 + NB_USERS: 10 + healthcheck: + test: /bin/bash -c "pgrep oai_hss" + interval: 10s + timeout: 5s + retries: 5 + + oai_mme: + image: oai-mme:production + container_name: prod-oai-mme + privileged: true + depends_on: [oai_hss] + networks: + public_net: + ipv4_address: 192.168.61.3 + environment: + REALM: openairinterface.org + PREFIX: /openair-mme/etc + INSTANCE: 1 + PID_DIRECTORY: /var/run + HSS_IP_ADDR: 192.168.61.2 + HSS_HOSTNAME: hss + HSS_FQDN: hss.openairinterface.org + HSS_REALM: openairinterface.org + MCC: '222' + MNC: '01' + MME_GID: 32768 + MME_CODE: 3 + TAC_0: 1 + TAC_1: 2 + TAC_2: 3 + MME_FQDN: mme.openairinterface.org + MME_S6A_IP_ADDR: 192.168.61.3 + MME_INTERFACE_NAME_FOR_S1_MME: eth0 + MME_IPV4_ADDRESS_FOR_S1_MME: 192.168.61.3 + MME_INTERFACE_NAME_FOR_S11: eth0 + MME_IPV4_ADDRESS_FOR_S11: 192.168.61.3 + MME_INTERFACE_NAME_FOR_S10: lo + MME_IPV4_ADDRESS_FOR_S10: 127.0.0.10 + OUTPUT: CONSOLE + SGW_IPV4_ADDRESS_FOR_S11_0: 192.168.61.4 + PEER_MME_IPV4_ADDRESS_FOR_S10_0: 0.0.0.0 + PEER_MME_IPV4_ADDRESS_FOR_S10_1: 0.0.0.0 + MCC_SGW_0: '222' + MNC3_SGW_0: '001' + TAC_LB_SGW_0: '01' + TAC_HB_SGW_0: '00' + MCC_MME_0: '222' + MNC3_MME_0: '001' + TAC_LB_MME_0: '02' + TAC_HB_MME_0: '00' + MCC_MME_1: '222' + MNC3_MME_1: '001' + TAC_LB_MME_1: '03' + TAC_HB_MME_1: '00' + TAC_LB_SGW_TEST_0: '03' + TAC_HB_SGW_TEST_0: '00' + SGW_IPV4_ADDRESS_FOR_S11_TEST_0: 0.0.0.0 + healthcheck: + test: /bin/bash -c "pgrep oai_mme" + interval: 10s + timeout: 5s + retries: 5 + + oai_spgwc: + image: oai-spgwc:production + privileged: true + depends_on: [oai_mme] + container_name: prod-oai-spgwc + networks: + public_net: + ipv4_address: 192.168.61.4 + environment: + PID_DIRECTORY: /var/run + SGW_INTERFACE_NAME_FOR_S11: eth0 + SGW_IP_FOR_S5_S8_CP: 127.0.0.11/8 + PGW_IP_FOR_S5_S8_CP: 127.0.0.12/8 + PGW_INTERFACE_NAME_FOR_SX: eth0 + DEFAULT_APN: oai.ipv4 + DEFAULT_DNS_IPV4_ADDRESS: 192.168.18.129 + DEFAULT_DNS_SEC_IPV4_ADDRESS: 8.8.4.4 + UE_IP_ADDRESS_POOL: '12.1.1.2 - 12.1.1.254' + PUSH_PROTOCOL_OPTION: 'yes' + healthcheck: + test: /bin/bash -c "pgrep oai_spgwc" + interval: 10s + timeout: 5s + retries: 5 + + oai_spgwu: + image: oai-spgwu-tiny:production + privileged: true + container_name: prod-oai-spgwu-tiny + depends_on: [oai_spgwc] + networks: + public_net: + ipv4_address: 192.168.61.5 + environment: + PID_DIRECTORY: /var/run + INSTANCE: 1 + SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP: eth0 + PGW_INTERFACE_NAME_FOR_SGI: eth0 + SGW_INTERFACE_NAME_FOR_SX: eth0 + SPGWC0_IP_ADDRESS: 192.168.61.4 + NETWORK_UE_IP: '12.1.1.0/24' + NETWORK_UE_NAT_OPTION: 'yes' + healthcheck: + test: /bin/bash -c "pgrep oai_spgwu" + interval: 10s + timeout: 5s + retries: 5 + + flexran_rtc: + image: flexran-rtc:production + privileged: true + container_name: prod-flexran-rtc + networks: + public_net: + ipv4_address: 192.168.61.10 + healthcheck: + test: /bin/bash -c "pgrep rt_controller" + interval: 10s + timeout: 5s + retries: 5 + + trf_gen: + image: trf-gen:production + privileged: true + container_name: prod-trf-gen + networks: + public_net: + ipv4_address: 192.168.61.11 + entrypoint: /bin/bash -c "ip route add 12.1.1.0/24 via 192.168.61.5 dev eth0; sleep infinity" + healthcheck: + test: /bin/bash -c "ping -c 2 192.168.61.5" + interval: 10s + timeout: 5s + retries: 5 + +networks: + private_net: + name: prod-oai-private-net + ipam: + config: + - subnet: 192.168.68.0/26 + public_net: + name: prod-oai-public-net + ipam: + config: + - subnet: 192.168.61.0/26 diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a75be0a221..22e0e480eb 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -23,6 +23,114 @@ cmake_minimum_required (VERSION 3.0) + +# System packages that are required +# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ +# or cmake provide a generic interface to pkg-config that widely used +################################### +include(FindPkgConfig) + +pkg_search_module(LIBXML2 libxml-2.0 REQUIRED) +include_directories(${LIBXML2_INCLUDE_DIRS}) + +pkg_search_module(LIBXSLT libxslt REQUIRED) +include_directories(${LIBXSLT_INCLUDE_DIRS}) + +pkg_search_module(OPENSSL openssl REQUIRED) +include_directories(${OPENSSL_INCLUDE_DIRS}) + +pkg_search_module(CONFIG libconfig REQUIRED) +include_directories(${CONFIG_INCLUDE_DIRS}) + +pkg_search_module(CRYPTO libcrypto REQUIRED) +include_directories(${CRYPTO_INCLUDE_DIRS}) + +#use native cmake method as this package is not in pkg-config +if (${RF_BOARD} STREQUAL "OAI_USRP") + find_package(Boost REQUIRED) + include_directories(${LIBBOOST_INCLUDE_DIR}) + +elseif (${RF_BOARD} STREQUAL "OAI_IRIS") + include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") + include_directories("/usr/local/include/") + set(HW_SOURCE ${HW_SOURCE} + ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) + LINK_DIRECTORIES("/usr/local/lib") + set(option_HW_lib "-lSoapySDR -rdynamic -ldl") + +endif (${RF_BOARD} STREQUAL "OAI_USRP") + +pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2) +if(NOT ${OPENPGM_FOUND}) + message("PACKAGE openpgm-5.1 is required by binaries such as oaisim: will fail later if this target is built") +else() + include_directories(${OPENPGM_INCLUDE_DIRS}) +endif() + +pkg_search_module(NETTLE nettle) +if(NOT ${NETTLE_FOUND}) + message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") +else() + include_directories(${NETTLE_INCLUDE_DIRS}) +endif() + +message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") + +string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) +string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) +message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") +message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") + +if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") + message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) +endif() + +add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") +add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") + +pkg_search_module(XPM xpm) +if(NOT ${XPM_FOUND}) + message("PACKAGE xpm not found: some targets will fail") +else() + include_directories(${XPM_INCLUDE_DIRS}) +endif() + +# Atlas is required by some packages, but not found in pkg-config +# So, here are some hacks here. Hope this gets fixed in future! +if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") + include_directories("/usr/include/atlas") + LINK_DIRECTORIES("/usr/lib/lapack") + LINK_DIRECTORIES("/usr/lib64") + LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here! + + if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7 + list(APPEND ATLAS_LIBRARIES blas) + + else() # Case for Ubuntu + list(APPEND ATLAS_LIBRARIES cblas) + endif() + + if(EXISTS "/usr/lib/atlas/libtatlas.so" OR EXISTS "/usr/lib64/atlas/libtatlas.so") #Case for CentOS7 + list(APPEND ATLAS_LIBRARIES tatlas) + else() + list(APPEND ATLAS_LIBRARIES atlas) #Case for Ubuntu + endif() + + list(APPEND ATLAS_LIBRARIES lapack) + +# for ubuntu 17.10, directories are different +elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h") + + include_directories("/usr/include/x86_64-linux-gnu") + LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") + list(APPEND ATLAS_LIBRARIES cblas) + list(APPEND ATLAS_LIBRARIES atlas) + list(APPEND ATLAS_LIBRARIES lapack) + +else() + message("No Blas/Atlas libs found, some targets will fail") +endif() + ######################################################### # Base directories, compatible with legacy OAI building # ######################################################### @@ -232,8 +340,8 @@ 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} -g3 -DMALLOC_CHECK_=3") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g3 -O0 -DMALLOC_CHECK_=3") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g3 -DMALLOC_CHECK_=3 -O2 -fno-delete-null-pointer-checks") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3") set(GIT_BRANCH "UNKNOWN") @@ -302,7 +410,6 @@ set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) add_library(ITTI ${OCP_ITTI}/intertask_interface.cpp ${OPENAIR_DIR}/common/utils/backtrace.c - ${OPENAIR_DIR}/common/utils/memory_pools.c ) add_dependencies(ITTI rrc_flag) set(ITTI_LIB ITTI) @@ -356,9 +463,9 @@ include_directories ("${RRC_FULL_DIR}") #NR RRC ####### -set (NR_RRC_ASN1_VERSION "NR_Rel15" ) -make_version(NR_RRC_VERSION 15 6 0) -set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-15.6.0.asn1) +set (NR_RRC_ASN1_VERSION "NR_Rel16" ) +make_version(NR_RRC_VERSION 16 1 0) +set (NR_RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.1.0.asn1) add_definitions(-DNR_RRC_VERSION=${NR_RRC_VERSION}) set (NR_RRC_FULL_DIR ${asn1_generated_dir}/RRC_${NR_RRC_ASN1_VERSION}) @@ -436,6 +543,59 @@ add_library(S1AP_ENB add_dependencies(S1AP_ENB rrc_flag s1ap_flag) +# NGAP +# Same limitation as described in RRC: unknown generated file list +# so we generate it at cmake time +############## +set (NGAP_RELEASE R15) + +set(NGAP_DIR ${OPENAIR3_DIR}/NGAP) +make_version(NGAP_VERSION 15 8 0) +set(NGAP_ASN_FILES "ngap-15.8.0.asn1") + +add_definitions(-DNGAP_VERSION=${NGAP_VERSION}) +set(NGAP_ASN_DIR ${NGAP_DIR}/MESSAGES/ASN1/ASN1_files) +set(NGAP_C_DIR ${asn1_generated_dir}/NGAP_${NGAP_RELEASE}) + +# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make +execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" "NGAP_" -fno-include-deps -findirect-choice + RESULT_VARIABLE ret) +if (NOT ${ret} STREQUAL 0) + message(FATAL_ERROR "${ret}: error") +endif (NOT ${ret} STREQUAL 0) +file(GLOB NGAP_source ${NGAP_C_DIR}/*.c) + +add_custom_target ( + ngap_flag ALL + ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${NGAP_C_DIR}" "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" "NGAP_" -fno-include-deps + DEPENDS "${NGAP_ASN_DIR}/${NGAP_ASN_FILES}" +) + +add_library(NGAP_LIB + ${NGAP_source} +# ${NGAP_DIR}/ngap_common.c + ) +add_dependencies(NGAP_LIB rrc_flag ngap_flag) + +include_directories ("${NGAP_C_DIR}") +include_directories ("${NGAP_DIR}") + +add_library(NGAP_GNB + ${NGAP_DIR}/ngap_gNB.c + ${NGAP_DIR}/ngap_gNB_context_management_procedures.c + ${NGAP_DIR}/ngap_gNB_decoder.c + ${NGAP_DIR}/ngap_gNB_encoder.c + ${NGAP_DIR}/ngap_gNB_handlers.c + ${NGAP_DIR}/ngap_gNB_itti_messaging.c + ${NGAP_DIR}/ngap_gNB_management_procedures.c + ${NGAP_DIR}/ngap_gNB_nas_procedures.c + ${NGAP_DIR}/ngap_gNB_nnsf.c + ${NGAP_DIR}/ngap_gNB_overload.c + ${NGAP_DIR}/ngap_gNB_trace.c + ${NGAP_DIR}/ngap_gNB_ue_context.c + ) +add_dependencies(NGAP_GNB rrc_flag ngap_flag) + #M2AP # Same limitation as described in RRC/S1AP: unknown generated file list # so we generate it at cmake time @@ -622,7 +782,7 @@ add_library(X2AP_ENB ${X2AP_DIR}/x2ap_ids.c ${X2AP_DIR}/x2ap_timers.c ) -add_dependencies(X2AP_ENB rrc_flag x2_flag) +add_dependencies(X2AP_ENB X2AP_LIB rrc_flag x2_flag) # F1AP @@ -813,7 +973,7 @@ Message("CPU_Affinity flag is ${CPU_AFFINITY}") add_boolean_option(NO_RRM True "DO WE HAVE A RADIO RESSOURCE MANAGER: NO") add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????") -add_boolean_option(DEADLINE_SCHEDULER True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14") +add_boolean_option(DEADLINE_SCHEDULER False "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14") add_boolean_option(CPU_AFFINITY False "Enable CPU Affinity of threads (only valid without deadline scheduler). It is enabled only with >2 CPUs") add_boolean_option(NAS_NETLINK False "useless ??? Must be True to compile nasmesh driver without rtai ????") add_boolean_option(OAI_NW_DRIVER_USE_NETLINK True "????") @@ -826,6 +986,7 @@ add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION w add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE") +add_boolean_option(ITTI_SIM False "enable itti simulator") ######################## # Include order @@ -835,9 +996,9 @@ add_boolean_option(ENB_MODE True "Swap the include directories between openair2 ########################## # SCHEDULING/REAL-TIME/PERF options ########################## -add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME True "Add data in vcd traces: disable it if perf issues") -add_boolean_option(ENABLE_VCD True "always true now, time measurements of proc calls and var displays") -add_boolean_option(ENABLE_VCD_FIFO True "time measurements of proc calls and var displays sent to FIFO (one more thread)") +add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME False "Add data in vcd traces: disable it if perf issues") +add_boolean_option(ENABLE_VCD False "always true now, time measurements of proc calls and var displays") +add_boolean_option(ENABLE_VCD_FIFO False "time measurements of proc calls and var displays sent to FIFO (one more thread)") add_boolean_option(LINUX False "used in weird memcpy() in pdcp.c ???") add_boolean_option(LINUX_LIST False "used only in lists.c: either use OAI implementation of lists or Linux one (should be True, but it is False") add_boolean_option(OPENAIR_LTE True "Seems legacy: keep it to true") @@ -1095,9 +1256,22 @@ add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/flexran_agent_async.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c + ${OPENAIR2_DIR}/ENB_APP/flexran_agent_app.c ) add_dependencies(FLEXRAN_AGENT rrc_flag) set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) +add_library(flapp_sample SHARED + ${OPENAIR2_DIR}/ENB_APP/flexran_apps/sample.c +) +set_target_properties(flapp_sample PROPERTIES C_VISIBILITY_PRESET hidden) +add_library(flapp_imsi SHARED + ${OPENAIR2_DIR}/ENB_APP/flexran_apps/imsi.c +) +set_target_properties(flapp_imsi PROPERTIES C_VISIBILITY_PRESET hidden) +add_custom_target(flapp_all DEPENDS + flapp_sample + flapp_imsi +) #include_directories(${OPENAIR2_DIR}/ENB_APP) set(PROTOBUF_LIB "protobuf-c") @@ -1238,6 +1412,7 @@ set(SECU_OSA_SRC ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c ) add_library(SECU_OSA ${SECU_OSA_SRC}) +target_link_libraries(SECU_OSA ${NETTLE_LIBRARIES}) set(SECU_CN_SRC ${OPENAIR3_DIR}/SECU/kdf.c @@ -1251,6 +1426,8 @@ set(SECU_CN_SRC ) add_library(SECU_CN ${SECU_CN_SRC}) +target_link_libraries(SECU_CN ${NETTLE_LIBRARIES}) + # Physical Channel Procedures Scheduling ################################" set(SCHED_SRC @@ -1580,6 +1757,7 @@ 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/ul_ref_seq_nr.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c @@ -1616,6 +1794,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/sss_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/cic_filter_nr.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_initial_sync.c + ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_pbch.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -1789,6 +1968,7 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c ) set(L2_SRC @@ -1841,6 +2021,7 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB_internode.c ${NR_RRC_DIR}/rrc_gNB_reconfig.c ${NR_RRC_DIR}/rrc_gNB_UE_context.c + ${NR_RRC_DIR}/rrc_gNB_NGAP.c ) set(L2_SRC_UE @@ -1928,10 +2109,10 @@ set (MAC_NR_SRC_UE ${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_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ${NR_UE_MAC_DIR}/nr_l1_helpers.c ${NR_UE_MAC_DIR}/nr_ra_procedures.c - ${NR_UE_MAC_DIR}/rar_tools_nrUE.c ) set (ENB_APP_SRC @@ -2036,6 +2217,11 @@ set (GTPV1U_SRC add_library(GTPV1U ${GTPV1U_SRC}) add_dependencies(GTPV1U rrc_flag) +#add_library (GTPV1U_OCP +#${OPENAIR3_DIR}/ocp-gtp/gtp_itf.cpp +#) +#include_directories(${OPENAIR3_DIR}/ocp-gtp) + #NR case set (NR_GTPV1U_SRC ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c @@ -2327,6 +2513,134 @@ if(NAS_UE) endif() +if(ITTI_SIM) + set(libnas_ue_api_OBJS + ${NAS_SRC}UE/API/USER/at_command.c + ${NAS_SRC}UE/API/USER/at_error.c + ${NAS_SRC}UE/API/USER/at_response.c + ${NAS_SRC}UE/API/USER/user_api.c + ${NAS_SRC}UE/API/USER/user_indication.c + ${NAS_SRC}UE/API/USIM/aka_functions.c + ${NAS_SRC}UE/API/USIM/usim_api.c + ) + set(libnas_ue_emm_OBJS + ${NAS_SRC}UE/EMM/Attach.c + ${NAS_SRC}UE/EMM/Authentication.c + ${NAS_SRC}UE/EMM/Detach.c + ${NAS_SRC}UE/EMM/emm_main.c + ${NAS_SRC}UE/EMM/EmmStatusHdl.c + ${NAS_SRC}UE/EMM/Identification.c + ${NAS_SRC}UE/EMM/IdleMode.c + ${NAS_SRC}UE/EMM/LowerLayer.c + ${NAS_SRC}UE/EMM/SecurityModeControl.c + ${NAS_SRC}UE/EMM/ServiceRequestHdl.c + ${NAS_SRC}UE/EMM/TrackingAreaUpdate.c + ) + set(libnas_ue_emm_sap_OBJS + ${NAS_SRC}UE/EMM/SAP/emm_as.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttachNeeded.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregistered.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredInitiated.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredLimitedService.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoImsi.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNormalService.c + ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredPlmnSearch.c + ${NAS_SRC}UE/EMM/SAP/emm_esm.c + ${NAS_SRC}UE/EMM/SAP/emm_fsm.c + ${NAS_SRC}UE/EMM/SAP/EmmNull.c + ${NAS_SRC}UE/EMM/SAP/emm_recv.c + ${NAS_SRC}UE/EMM/SAP/emm_reg.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c + ${NAS_SRC}UE/EMM/SAP/EmmRegistered.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredInitiated.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredLimitedService.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNoCellAvailable.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNormalService.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredPlmnSearch.c + ${NAS_SRC}UE/EMM/SAP/EmmRegisteredUpdateNeeded.c + ${NAS_SRC}UE/EMM/SAP/emm_sap.c + ${NAS_SRC}UE/EMM/SAP/emm_send.c + ${NAS_SRC}UE/EMM/SAP/EmmServiceRequestInitiated.c + ${NAS_SRC}UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c + ) + set (libnas_ue_esm_OBJS + ${NAS_SRC}UE/ESM/DedicatedEpsBearerContextActivation.c + ${NAS_SRC}UE/ESM/DefaultEpsBearerContextActivation.c + ${NAS_SRC}UE/ESM/EpsBearerContextDeactivation.c + ${NAS_SRC}UE/ESM/esm_ebr.c + ${NAS_SRC}UE/ESM/esm_ebr_context.c + ${NAS_SRC}UE/ESM/esm_ip.c + ${NAS_SRC}UE/ESM/esm_main.c + ${NAS_SRC}UE/ESM/esm_pt.c + ${NAS_SRC}UE/ESM/EsmStatusHdl.c + ${NAS_SRC}UE/ESM/PdnConnectivity.c + ${NAS_SRC}UE/ESM/PdnDisconnect.c + ) + set(libnas_ue_esm_sap_OBJS + ${NAS_SRC}UE/ESM/SAP/esm_recv.c + ${NAS_SRC}UE/ESM/SAP/esm_send.c + ${NAS_SRC}UE/ESM/SAP/esm_sap.c + ) + + set(libnrnas_emm_msg_OBJS + ${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c + ${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c + ${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c + ${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c + ${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c + ${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c + ${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c + ${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c + ) + + set(libnrnas_ies_OBJS + ${NAS_SRC}COMMON/IES/ExtendedProtocolDiscriminator.c + ${NAS_SRC}COMMON/IES/FGSMobileIdentity.c + ${NAS_SRC}COMMON/IES/FGSRegistrationType.c + ${NAS_SRC}COMMON/IES/SpareHalfOctet.c + ${NAS_SRC}COMMON/IES/FGSRegistrationResult.c + ${NAS_SRC}COMMON/IES/FGMMCapability.c + ${NAS_SRC}COMMON/IES/NrUESecurityCapability.c + ${NAS_SRC}COMMON/IES/FGCNasMessageContainer.c + ${NAS_SRC}COMMON/IES/SORTransparentContainer.c + ) + + add_library(LIB_NAS_SIMUE + ${NAS_SRC}UE/nas_itti_messaging.c + ${NAS_SRC}UE/nas_network.c + ${NAS_SRC}UE/nas_parser.c + ${NAS_SRC}UE/nas_proc.c + ${NAS_SRC}UE/nas_user.c + ${NAS_SRC}NR_UE/nr_nas_msg_sim.c + ${libnas_api_OBJS} + ${libnas_ue_api_OBJS} + ${libnas_emm_msg_OBJS} + ${libnas_esm_msg_OBJS} + ${libnas_ies_OBJS} + ${libnas_utils_OBJS} + ${libnas_ue_emm_OBJS} + ${libnas_ue_emm_sap_OBJS} + ${libnas_ue_esm_OBJS} + ${libnas_ue_esm_sap_OBJS} + ${libnrnas_emm_msg_OBJS} + ${libnrnas_ies_OBJS} + ) + add_dependencies(LIB_NAS_SIMUE rrc_flag) + set(NAS_SIM_LIB LIB_NAS_SIMUE) + + include_directories(${NAS_SRC}NR_UE) + include_directories(${NAS_SRC}UE) + include_directories(${NAS_SRC}UE/API/USER) + include_directories(${NAS_SRC}UE/API/USIM) + include_directories(${NAS_SRC}UE/EMM) + include_directories(${NAS_SRC}UE/EMM/SAP) + include_directories(${NAS_SRC}UE/ESM) + include_directories(${NAS_SRC}UE/ESM/SAP) +endif() + # nbiot add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16") set (NBIOT_SOURCES @@ -2339,6 +2653,14 @@ set (SHLIB_LOADER_SOURCES ${OPENAIR_DIR}/common/utils/load_module_shlib.c ) +add_library(LIB_5GNAS_GNB + ${NAS_SRC}/COMMON/nr_common.c + ${NAS_SRC}/gNB/network_process_nas.c + ${NAS_SRC}/NR_UE/ue_process_nas.c + ${OPENAIR3_DIR}//UICC/usim_interface.c + ) +target_link_libraries(LIB_5GNAS_GNB SECU_CN ${CRYPTO_LIBRARIES}) + # Make lfds as a own source code (even if it is a outside library) # For better intergration with compilation flags & structure of cmake ################################################################### @@ -2415,114 +2737,6 @@ include_directories("${NFAPI_DIR}/nfapi/inc") include_directories("${NFAPI_DIR}/sim_common/inc") include_directories("${NFAPI_DIR}/pnf_sim/inc") - -# System packages that are required -# We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ -# or cmake provide a generic interface to pkg-config that widely used -################################### -include(FindPkgConfig) - -pkg_search_module(LIBXML2 libxml-2.0 REQUIRED) -include_directories(${LIBXML2_INCLUDE_DIRS}) - -pkg_search_module(LIBXSLT libxslt REQUIRED) -include_directories(${LIBXSLT_INCLUDE_DIRS}) - -pkg_search_module(OPENSSL openssl REQUIRED) -include_directories(${OPENSSL_INCLUDE_DIRS}) - -pkg_search_module(CONFIG libconfig REQUIRED) -include_directories(${CONFIG_INCLUDE_DIRS}) - -pkg_search_module(CRYPTO libcrypto REQUIRED) -include_directories(${CRYPTO_INCLUDE_DIRS}) - -#use native cmake method as this package is not in pkg-config -if (${RF_BOARD} STREQUAL "OAI_USRP") - find_package(Boost REQUIRED) - include_directories(${LIBBOOST_INCLUDE_DIR}) - -elseif (${RF_BOARD} STREQUAL "OAI_IRIS") - include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") - include_directories("/usr/local/include/") - set(HW_SOURCE ${HW_SOURCE} - ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) - LINK_DIRECTORIES("/usr/local/lib") - set(option_HW_lib "-lSoapySDR -rdynamic -ldl") - -endif (${RF_BOARD} STREQUAL "OAI_USRP") - -pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2) -if(NOT ${OPENPGM_FOUND}) - message("PACKAGE openpgm-5.1 is required by binaries such as oaisim: will fail later if this target is built") -else() - include_directories(${OPENPGM_INCLUDE_DIRS}) -endif() - -pkg_search_module(NETTLE nettle) -if(NOT ${NETTLE_FOUND}) - message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") -else() - include_directories(${NETTLE_INCLUDE_DIRS}) -endif() - -message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") - -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - -pkg_search_module(XPM xpm) -if(NOT ${XPM_FOUND}) - message("PACKAGE xpm not found: some targets will fail") -else() - include_directories(${XPM_INCLUDE_DIRS}) -endif() - -# Atlas is required by some packages, but not found in pkg-config -# So, here are some hacks here. Hope this gets fixed in future! -if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h") - include_directories("/usr/include/atlas") - LINK_DIRECTORIES("/usr/lib/lapack") - LINK_DIRECTORIES("/usr/lib64") - LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here! - - if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7 - list(APPEND ATLAS_LIBRARIES blas) - - else() # Case for Ubuntu - list(APPEND ATLAS_LIBRARIES cblas) - endif() - - if(EXISTS "/usr/lib/atlas/libtatlas.so" OR EXISTS "/usr/lib64/atlas/libtatlas.so") #Case for CentOS7 - list(APPEND ATLAS_LIBRARIES tatlas) - else() - list(APPEND ATLAS_LIBRARIES atlas) #Case for Ubuntu - endif() - - list(APPEND ATLAS_LIBRARIES lapack) - -# for ubuntu 17.10, directories are different -elseif(EXISTS "/usr/include/x86_64-linux-gnu/cblas.h") - - include_directories("/usr/include/x86_64-linux-gnu") - LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu") - list(APPEND ATLAS_LIBRARIES cblas) - list(APPEND ATLAS_LIBRARIES atlas) - list(APPEND ATLAS_LIBRARIES lapack) - -else() - message("No Blas/Atlas libs found, some targets will fail") -endif() - list(APPEND ATLAS_LIBRARIES lapack lapacke) include_directories ("/usr/include/X11") @@ -2629,6 +2843,12 @@ add_executable(measurement_display ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) target_link_libraries (measurement_display minimal_lib) +add_executable(test5Gnas + ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c +) +target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib ) + + # lte-softmodem is both eNB and UE implementation ################################################### @@ -2670,7 +2890,7 @@ target_link_libraries (lte-softmodem -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem ${T_LIB}) @@ -2709,7 +2929,7 @@ target_link_libraries (ocp-enb PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON ${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) -target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) +target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) add_executable(cu_test ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c @@ -2781,7 +3001,7 @@ target_link_libraries (lte-uesoftmodem -Wl,--end-group z dl) target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${T_LIB}) @@ -2819,16 +3039,57 @@ target_link_libraries (nr-softmodem -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB - S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} -Wl,--end-group z dl) target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) + +add_executable(ocp-gnb + ${rrc_h} + ${nr_rrc_h} + ${s1ap_h} +# ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_DIR}/executables/ocp-gnb.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${OPENAIR_DIR}/executables/softmodem-common.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.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/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${GTPU_need_ITTI} + ${XFORMS_SOURCE_NR} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ${XFORMSINTERFACE_SOURCE} + ) + +target_link_libraries (ocp-gnb + -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 NR_GTPV1U SECU_CN SECU_OSA + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB + NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON + -Wl,--end-group z dl) + +target_link_libraries (ocp-gnb ${LIBXML2_LIBRARIES} ) +target_link_libraries (ocp-gnb pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (ocp-gnb ${LIB_LMS_LIBRARIES}) +target_link_libraries (ocp-gnb ${T_LIB}) +add_dependencies(ocp-gnb ldpc_orig ldpc_optim ldpc_optim8seg ldpc params_libconfig rfsimulator oai_usrpdevif rfsimulator nrscope) + + # nr-uesoftmodem is UE implementation ####################################### @@ -2860,14 +3121,14 @@ add_executable(nr-uesoftmodem target_link_libraries (nr-uesoftmodem -Wl,--start-group - RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB + RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB S1AP_LIB S1AP_ENB - ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB -Wl,--end-group z dl) target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) @@ -2981,6 +3242,7 @@ add_executable(nr_dlschsim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -2995,6 +3257,7 @@ add_executable(nr_pbchsim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -3011,6 +3274,7 @@ add_executable(nr_pucchsim ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -3029,12 +3293,13 @@ add_executable(nr_dlsim ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${NFAPI_USER_DIR}/nfapi.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim - -Wl,--start-group UTIL SIMU_COMMON 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 HASHTABLE -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON 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_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3048,11 +3313,13 @@ add_executable(nr_prachsim ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${NFAPI_USER_DIR}/nfapi.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB HASHTABLE -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group + m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c @@ -3084,7 +3351,7 @@ add_executable(nr_ulsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_ulsim - -Wl,--start-group UTIL SIMU_COMMON 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 HASHTABLE -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON 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_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3119,7 +3386,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) add_executable(test_epc_play_scenario @@ -3138,7 +3405,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) @@ -3158,7 +3425,7 @@ foreach(myExe s1ap ${OPENAIR3_DIR}/TEST/test_${myExe}.c ) target_link_libraries (test_${myExe} - -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) endforeach(myExe) @@ -3171,7 +3438,7 @@ if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) lte-softmodem lte-uesoftmodem nr-softmodem - nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 + nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-ittisim ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test @@ -3183,7 +3450,7 @@ if (${T_TRACER}) SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL 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_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR + L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR NGAP_GNB CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts) if (TARGET ${i}) @@ -3258,6 +3525,53 @@ add_executable(rb_tool ) target_include_directories(rb_tool PRIVATE ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/) +# nr-ittisim +################################################### + +add_executable(nr-ittisim + ${rrc_h} + ${nr_rrc_h} + ${OPENAIR2_DIR}/GNB_APP/gnb_app.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config.c + ${OPENAIR_DIR}/executables/nr-gnb.c + ${OPENAIR_DIR}/executables/nr-ru.c + ${OPENAIR2_DIR}/SIMULATION/NR_RRC/itti_sim.c + ${OPENAIR_DIR}/executables/softmodem-common.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${GTPU_need_ITTI} + ${XFORMSINTERFACE_SOURCE} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) + +target_link_libraries (nr-ittisim + -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 NR_GTPV1U SECU_CN SECU_OSA + ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB + NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} + PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE + -Wl,--end-group z dl) + +target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES}) +target_link_libraries (nr-ittisim pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-ittisim ${LIB_LMS_LIBRARIES}) +target_link_libraries (nr-ittisim ${T_LIB}) + +add_dependencies( nr-ittisim ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) + # ??? #################### list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 7e43a9d01c..6d3424b420 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1095,7 +1095,12 @@ (Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16), (Test11: HARQ test 25% TP (4 rounds), (Test12: HARQ test 33% TP (3 rounds), - (Test13: HARQ test 50% TP (2 rounds) + (Test13: HARQ test 50% TP (2 rounds), + (Test14: 3 PTRS, 8 Interpolated Symbols), + (Test15: 6 PTRS, 5 Interpolated Symbols), + (Test16: 11 PTRS, 0 Interpolated Symbols), + (Test17: 2 DMRS Symbols), + (Test18: 3 DMRS Symbols) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1114,8 +1119,13 @@ -n100 -e16 -s10 -n100 -s1 -t25 -n100 -s1 -t33 - -n100 -s1 -t50 - 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 nr_dlsim.test12 nr_dlsim.test13 + -n100 -s1 -t50 + -n100 -s5 -T 2 2 2 + -n100 -s5 -T 2 1 2 + -n100 -s5 -T 2 0 4 + -n100 -s2 -U 2 0 1 + -n100 -s2 -U 2 0 2 + 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 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1279,7 +1289,10 @@ (Test5: MCS 9 273 PRBs), (Test6: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols), (Test7: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols), - (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols) + (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols), + (Test9: SC-FDMA, 50 PRBs), + (Test10: SC-FDMA, 75 PRBs), + (Test11: SC-FDMA, 3 DMRS) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1293,8 +1306,11 @@ -n100 -m9 -R273 -r273 -s5 -n100 -s5 -T 2 1 2 -U 2 0 2 -n100 -s5 -T 2 2 2 -U 2 1 2 - -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 - nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 + -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 + -n100 -s20 -Z + -n100 -s20 -Z -r75 + -n100 -s20 -Z -U 2 0 2 + nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1302,10 +1318,12 @@ execution - nr_prachsim Test cases. (Test1: 106 PRBs - Prach format A2), - (Test2: 217 PRBs - Prach format A2), - (Test3: 273 PRBs - Prach format A2), - (Test4: 106 PRBs - Prach format 0) + nr_prachsim Test cases. (Test1: 30kHz SCS, 106 PRBs, Prach format A2), + (Test2: 30kHz SCS, 217 PRBs, Prach format A2), + (Test3: 30kHz SCS, 273 PRBs, Prach format A2), + (Test4: 30kHz SCS, 106 PRBs, Prach format 0), + (Test5: 120kHz SCS, 32 PRBs, Prach format A2), + (Test6: 120kHz SCS, 66 PRBs, Prach format A2) $OPENAIR_DIR/cmake_targets/build_oai --phy_simulators -c @@ -1315,8 +1333,10 @@ -a -s -30 -n 100 -p 63 -R 106 -a -s -30 -n 100 -p 63 -R 217 -a -s -30 -n 100 -p 63 -R 273 - -a -s -30 -n 100 -p 63 -R 106 -c 4 - nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 + -a -s -30 -n 100 -p 63 -R 106 -c 4 + -a -s -30 -n 100 -p 32 -R 32 -m 3 -c52 + -a -s -30 -n 100 -p 32 -R 66 -m 3 -c52 + nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 PRACH test OK segmentation fault|assertion|exiting|fatal 3 diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index f301908495..960b241047 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -42,7 +42,6 @@ MSC_GEN=0 XFORMS="True" SKIP_SHARED_LIB_FLAG="False" UE_EXPANSION="False" -UESIM_EXPANSION="False" PRINT_STATS="False" VCD_TIMING="False" DEADLINE_SCHEDULER_FLAG_USER="" @@ -67,6 +66,7 @@ UE_TIMING_TRACE="False" USRP_REC_PLAY="False" BUILD_ECLIPSE=0 NR="False" +ITTI_SIM="False" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc" trap handle_ctrl_c INT @@ -160,6 +160,8 @@ Options Build for I/Q record-playback modes -k | --skip-shared-libraries Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes +--ittiSIM + Makes the itti simulator -h | --help Print this help @@ -264,10 +266,6 @@ function main() { UE_EXPANSION="True" echo_info "Will compile with UE_EXPANSION" shift;; - --musim) - UESIM_EXPANSION="True" - echo_info "Will compile with UESIM_EXPANSION" - shift;; --UE-conf-nvram) conf_nvram_path=$(readlink -f $2) shift 2;; @@ -418,6 +416,11 @@ function main() { CMAKE_CMD="$CMAKE_CMD -GNinja" MAKE_CMD=ninja shift;; + --ittiSIM) + ittiSIM=1 + ITTI_SIM="True" + echo_info "Will compile itti simulator" + shift;; -h | --help) print_help exit 1;; @@ -488,11 +491,6 @@ function main() { echo_info "Flags for Deadline scheduler: $DEADLINE_SCHEDULER_FLAG_USER" echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER" - if [ -n "$UHD_IMAGES_DIR" ] && [ -z "$INSTALL_EXTERNAL" ]; then - echo_error "UHD images download settings will not be applied without -I present" - exit - fi - ####################################################### # Setting and printing OAI envs, we should check here # ####################################################### @@ -549,9 +547,10 @@ function main() { # flash_firmware_iris #fi fi - echo_info "installing protobuf/protobuf-c for flexran agent support" + echo_info "Installing protobuf/protobuf-c for flexran agent support" install_protobuf_from_source install_protobuf_c_from_source + echo_success "protobuf/protobuf-c installation successful" fi if [ "$INSTALL_OPTIONAL" = "1" ] ; then @@ -580,7 +579,7 @@ function main() { config_libconfig_shlib=params_libconfig # first generate the CMakefile in the right directory - if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then + if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" -o "$ittiSIM" = "1" ] ; then # softmodem compilation @@ -592,7 +591,6 @@ function main() { echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file # echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file - echo "set ( UESIM_EXPANSION $UESIM_EXPANSION )" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file echo "set ( TRANSP_PRO \"${TP}\")" >> $cmake_file @@ -605,6 +603,7 @@ function main() { echo "set ( UE_TIMING_TRACE $UE_TIMING_TRACE )" >> $cmake_file echo "set ( USRP_REC_PLAY $USRP_REC_PLAY )" >> $cmake_file echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )" >> $cmake_file + echo "set ( ITTI_SIM $ITTI_SIM )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$build_dir/build eval $CMAKE_CMD @@ -626,6 +625,10 @@ function main() { execlist="$execlist nr-uesoftmodem" fi + if [ "$ittiSIM" = "1" ] ; then + execlist="$execlist nr-ittisim" + fi + for f in $execlist ; do echo_info "Compiling $f..." compilations \ @@ -647,14 +650,22 @@ function main() { $build_dir coding \ libcoding.so $dbin/libcoding.so - compilations \ - $build_dir nasmesh \ - CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko - compilations \ - $build_dir rb_tool \ - rb_tool $dbin/rb_tool - cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin + #check if we run inside a container or not + #IS_CONTAINER variable is defined in build_helper file + #compile nasmesh and rb_tool only if NOT running in a container + if [ $IS_CONTAINER -eq 0 ] + then + compilations \ + $build_dir nasmesh \ + CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko + + compilations \ + $build_dir rb_tool \ + rb_tool $dbin/rb_tool + + cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin + fi #IS_CONTAINER fi fi @@ -662,9 +673,16 @@ function main() { if [ "$UE" = 1 ] ; then echo_info "Compiling UE specific part" - compilations \ - $build_dir ue_ip \ - CMakeFiles/ue_ip/ue_ip.ko $dbin/ue_ip.ko + + if [ $IS_CONTAINER -eq 0 ] + then + echo_info "Building ue_ip module" + compilations \ + $build_dir ue_ip \ + CMakeFiles/ue_ip/ue_ip.ko $dbin/ue_ip.ko + else + echo_info "Bypassing ue_ip build" + fi #IS_CONTAINER # mkdir -p $DIR/at_commands/build # cd $DIR/at_commands/build diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20 new file mode 100755 index 0000000000..9ef79be9c2 --- /dev/null +++ b/cmake_targets/install_external_packages.ubuntu20 @@ -0,0 +1,505 @@ +#!/bin/bash +#/* +# * 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 +# */ + +# brief +# authors Laurent Thomas +# +####################################### +if [ ! -f /etc/os-release ]; then + echo "No /etc/os-release file found. You're likely on an unsupported distro." + exit 1 +fi +OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g") +OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g") +case "$OS_DISTRO" in + ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt"; CMAKE="cmake" ;; +esac + +SUDO='sudo -E' + +############################### +## echo and family +############################### +black='\E[30m' +red='\E[31m' +green='\E[32m' +yellow='\E[33m' +blue='\E[1;34m' +magenta='\E[35m' +cyan='\E[36m' +white='\E[37m' +reset_color='\E[00m' +COLORIZE=1 + +cecho() { + # Color-echo + # arg1 = message + # arg2 = color + local default_msg="No Message." + message=${1:-$default_msg} + color=${2:-$green} + [ "$COLORIZE" = "1" ] && message="$color$message$reset_color" + echo -e "$message" + return +} + +echo_error() { cecho "$* $red" ;} +echo_fatal() { cecho "$* $red"; exit 1 ;} +echo_warning() { cecho "$* $yellow" ;} +echo_success() { cecho "$* $green" ;} +echo_info() { cecho "$* $blue" ;} + +######################## +# distribution helpers # +######################## + +# This function return a string to identify the distribution we are running +# Examples: +# ubuntu16.04 +# debian8.5 +get_distribution_release() { + echo "$OS_DISTRO$OS_RELEASE" +} + +check_supported_distribution() { + case $(get_distribution_release) in + "ubuntu20.04") return 0 ;; + esac + return 1 +} + +################## +# Error handlers # +################## + +handler_EXIT() { + local exit_code=$? + [ "$exit_code" -eq 0 ] || echo_error "build have failed" + exit $exit_code +} + +trap handler_EXIT EXIT + +########################### +# Cleaners +########################### + +clean_kernel() { + $SUDO modprobe ip_tables + $SUDO modprobe x_tables + $SUDO iptables -P INPUT ACCEPT + $SUDO iptables -F INPUT + $SUDO iptables -P OUTPUT ACCEPT + $SUDO iptables -F OUTPUT + $SUDO iptables -P FORWARD ACCEPT + $SUDO iptables -F FORWARD + $SUDO iptables -t nat -F + $SUDO iptables -t mangle -F + $SUDO iptables -t filter -F + $SUDO iptables -t raw -F + echo_info "Flushed iptables" + $SUDO rmmod nasmesh > /dev/null 2>&1 + $SUDO rmmod oai_nw_drv > /dev/null 2>&1 + $SUDO rmmod openair_rf > /dev/null 2>&1 + $SUDO rmmod ue_ip > /dev/null 2>&1 + echo_info "removed drivers from kernel" +} + +clean_all_files() { + set_openair_env + rm -rf "$OPENAIR_DIR"/targets/bin/* + dir="$OPENAIR_DIR/cmake_targets" + rm -rf "$dir"/log/* + rm -rf "$dir"/ran_build/build + rm -rf "$dir"/ran_build_noLOG/build + rm -rf "$dir"/lte-simulators/build + rm -rf "$dir"/phy_simulators/build + rm -rf "$dir"/nas_sim_tools/build + rm -rf "$dir"/oaisim_build_oai/build + rm -rf "$dir"/oaisim_build_oai/CMakeLists.txt + rm -rf "$dir"/autotests/bin + rm -rf "$dir"/autotests/log + rm -rf "$dir"/autotests/*/build +} + +############################################ +# External packages installers +############################################ + +install_protobuf_from_source(){ + protobuf_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_install_log.txt + echo_info "\nInstalling Google Protobuf from sources. The log file for Protobuf installation is here: $protobuf_install_log " + ( + cd /tmp || exit + echo "Downloading protobuf" + #rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1 + #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz + #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner + #cd protobuf-2.6.1/ + rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 + wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner + cd protobuf-3.3.0/ || exit + ./configure + echo "Compiling protobuf" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$protobuf_install_log" +} + +install_protobuf_c_from_source(){ + protobuf_c_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_c_install_log.txt + echo_info "\nInstalling Google Protobuf_C from sources. The log file for Protobuf_C installation is here: $protobuf_c_install_log " + ( + if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + fi + cd /tmp || exit + echo "Downloading protobuf-c" + rm -rf /tmp/protobuf-c + git clone https://github.com/protobuf-c/protobuf-c.git + cd protobuf-c || exit + git checkout 2a46af42784abf86804d536f6e0122d47cfeea45 + ./autogen.sh + ./configure + echo "Compiling protobuf-c" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$protobuf_c_install_log" +} + +install_usrp_uhd_driver_from_source(){ + uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt + echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log " + ( + cd /tmp || exit + echo "Downloading UHD driver" + rm -rf /tmp/uhd + git clone https://github.com/EttusResearch/uhd.git + cd uhd || exit + git checkout tags/v3.13.0.2 + mkdir -p host/build + cd host/build || exit + $CMAKE ../ + echo "Compiling UHD" + make -j"$(nproc)" + make test + $SUDO make install + $SUDO ldconfig + ) >& "$uhd_install_log" +} + +install_bladerf_driver_from_source(){ + bladerf_install_log=$OPENAIR_DIR/cmake_targets/log/bladerf_install_log.txt + echo_info "\nInstalling BladeRF driver from sources. The log file for BladeRF driver installation is here: $bladerf_install_log " + ( + cd /tmp || exit + echo "Downloading BladeRF driver" + rm -rf /tmp/bladeRF + git clone https://github.com/Nuand/bladeRF.git + cd bladeRF || exit + git checkout tags/2016.06 + mkdir -p build + cd build || exit + $CMAKE ../ + echo "Compiling BladeRF driver" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + echo "Downloading FPGA and firmware images" + cd /tmp/bladeRF || exit + wget --tries=3 --retry-connrefused https://www.nuand.com/fx3/bladeRF_fw_latest.img + wget --tries=3 --retry-connrefused https://www.nuand.com/fpga/hostedx40-latest.rbf + sudo mkdir -p /usr/share/Nuand/bladeRF + sudo mv bladeRF_fw_latest.img /usr/share/Nuand/bladeRF/bladeRF_fw.img + sudo mv hostedx40-latest.rbf /usr/share/Nuand/bladeRF/hostedx40.rbf + ) >& "$bladerf_install_log" +} + +check_install_bladerf_driver(){ + if [[ "$OS_DISTRO" == "ubuntu" ]]; then + $SUDO apt-get install -y bladerf libbladerf-dev + $SUDO apt-get install -y bladerf-firmware-fx3 + $SUDO apt-get install -y bladerf-fpga-hostedx40 + elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then + install_bladerf_driver_from_source + else + echo_error "BladeRF Installer for OAI does not support automatic build. Install BladeRF compiling sources manually from BladeRF website" + fi +} + +flash_firmware_bladerf() { + $SUDO bladeRF-cli --flash-firmware /usr/share/Nuand/bladeRF/bladeRF_fw.img +} + +install_soapy_from_source(){ + soapy_install_log=$OPENAIR_DIR/cmake_targets/log/soapy_install_log.txt + echo_info "\nInstalling Soapy EcoSystem from source. The log file for Soapy installation is here: $soapy_install_log " + ( + cd /tmp || exit + echo "Downloading SoapySDR" + rm -rf /tmp/soapysdr + git clone -b soapy-sdr-0.7.0 --single-branch https://github.com/pothosware/SoapySDR.git + cd SoapySDR || exit + #git checkout tags/release_003_010_001_001 + mkdir -p build + cd build || exit + $CMAKE ../ + echo "Compiling SoapySDR" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + cd /tmp || exit + echo "Downloading SoapyRemote" + rm -rf /tmp/soapyremote + git clone -b soapy-remote-0.5.0 --single-branch https://github.com/pothosware/SoapyRemote.git + cd SoapyRemote || exit + #git checkout tags/release_003_010_001_001 + mkdir -p build + cd build || exit + cmake ../ + echo "Compiling SoapyRemote" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$soapy_install_log" +} + +install_soapy_iris_from_source(){ + iris_install_log=$OPENAIR_DIR/cmake_targets/log/iris_install_log.txt + echo_info "\nInstalling Iris driver from source. The log file for Iris driver installation is here: $iris_install_log " + ( + cd /tmp || exit + echo "Downloading SoapyIris" + rm -rf /tmp/sklk-soapyiris + git clone -b soapy-iris-2018.08.0.1 --single-branch https://github.com/skylarkwireless/sklk-soapyiris.git + cd sklk-soapyiris || exit + mkdir -p build + cd build ||exit + cmake ../ + echo "Compiling SoapyIris" + make -j"$(nproc)" + $SUDO make install + $SUDO ldconfig + ) >& "$iris_install_log" +} + +check_install_soapy () { + #if [[ "$OS_DISTRO" == "ubuntu" ]]; then + #first we remove old installation + $SUDO apt-get remove -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote || true + #$SUDO add-apt-repository -y ppa:myriadrf/drivers + #$SUDO apt-get update + #$SUDO apt-get install -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote + + #elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then + # $SUDO $INSTALLER -y install software-properties-common python3-software-properties python-software-properties subversion git python3 python-numpy python3-numpy cmake swig python-dev + install_soapy_from_source + #fi + install_soapy_iris_from_source + +} + +check_install_ubuntu_packages() { + $SUDO $INSTALLER update -y + if [[ "$OS_DISTRO" == "ubuntu" ]]; then + local LAPACK_LIBNAME="liblapack.so" + local LAPACK_TARGET="/usr/lib/atlas-base/atlas/liblapack.so" + $SUDO apt install -y software-properties-common + case "$(get_distribution_release)" in + "ubuntu20.04") + specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev" + LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" + LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + ;; + esac + $SUDO $INSTALLER install -y \ + $specific_packages \ + check \ + dialog \ + dkms \ + gawk \ + libboost-all-dev \ + libpthread-stubs0-dev \ + openvpn \ + pkg-config \ + python3-dev \ + python-pexpect \ + sshfs \ + swig \ + tshark \ + uml-utilities \ + unzip \ + valgrind \ + vlan \ + exuberant-ctags \ + ntpdate \ + iperf3 \ + android-tools-adb \ + wvdial \ + python-numpy \ + sshpass \ + nscd \ + bc \ + ntp \ + python3-scipy \ + python3-matplotlib \ + bison \ + build-essential \ + cmake \ + cmake-curses-gui \ + ninja-build \ + doxygen \ + doxygen-gui \ + texlive-latex-base \ + ethtool \ + flex \ + gdb \ + git \ + graphviz \ + gtkwave \ + guile-2.0-dev \ + iperf \ + iptables \ + libxtables-dev \ + libatlas-base-dev \ + libblas-dev \ + liblapack-dev\ + liblapacke-dev\ + libffi-dev \ + libforms-bin \ + libforms-dev \ + libgcrypt20-dev \ + libgmp-dev \ + libgtk-3-dev \ + libidn2-0-dev \ + libidn11-dev \ + libmysqlclient-dev \ + libpython2.7-dev \ + libsctp1 \ + libsctp-dev \ + libssl-dev \ + libtool \ + libusb-1.0-0-dev \ + libxml2 \ + libxml2-dev \ + libxslt1-dev \ + mscgen \ + octave-signal \ + openssh-client \ + openssh-server \ + openssl \ + python3 \ + subversion \ + xmlstarlet \ + python3-pip \ + libyaml-dev \ + wget \ + libxpm-dev \ + libboost-all-dev \ + nettle-dev \ + nettle-bin + fi + + $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" + +} + +install_asn1c_from_source(){ + asn1_install_log=$OPENAIR_DIR/cmake_targets/log/asn1c_install_log.txt + echo_info "\nInstalling ASN1. The log file for ASN1 installation is here: $asn1_install_log " + ( + $SUDO rm -rf /tmp/asn1c + # GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c + git clone https://gitlab.eurecom.fr/oai/asn1c.git /tmp/asn1c + cd /tmp/asn1c || exit + # better to use a given commit than a branch in case the branch + # is updated and requires modifications in the source of OAI + #git checkout velichkov_s1ap_plus_option_group + git checkout f12568d617dbf48497588f8e227d70388fa217c9 + autoreconf -iv + ./configure + make -j"$(nproc)" + $SUDO make install + cd - || exit + $SUDO ldconfig + ) > "$asn1_install_log" 2>&1 +} + +################################################# +# 2. compile +################################################ + +install_nas_tools() { + echo_success "generate .ue_emm.nvram .ue.nvram" + ./nvram --gen -c "$1" -o "$2" + ./usim --gen -c "$1" -o "$2" +} + + +################################ +# set_openair_env +############################### +set_openair_env(){ + fullpath=$(readlink -f "${BASH_SOURCE[0]}") + [ -f "/.$fullpath" ] || fullpath=$(readlink -f "$PWD/$fullpath") + openair_path=${fullpath%/cmake_targets/*} + openair_path=${openair_path%/targets/*} + openair_path=${openair_path%/openair[123]/*} + export OPENAIR_DIR=$openair_path + export OPENAIR1_DIR=$openair_path/openair1 + export OPENAIR2_DIR=$openair_path/openair2 + export OPENAIR3_DIR=$openair_path/openair3 + export OPENAIR_TARGETS=$openair_path/targets +} + +if ! check_supported_distribution; then + echo_error "Your distribution $(get_distribution_release) is not supported by oai !" + exit 1 +fi + +echo_info "Installing packages" +check_install_ubuntu_packages + +echo_info "installing ASN.1 compiler" +install_asn1c_from_source + +echo_info "installing protobuf/protobuf-c for flexran agent support" +install_protobuf_from_source +install_protobuf_c_from_source + +if [ "$1" == "USRP" ] ; then + echo_info "installing packages for USRP support" + install_usrp_uhd_driver +fi +if [ "$1" == "BLADERF" ] ; then + echo_info "installing packages for BLADERF support" + check_install_bladerf_driver + flash_firmware_bladerf +fi +if [ "$1" == "IRIS" ] ; then + echo_info "installing packages for IRIS support" + check_install_soapy + # flash_firmware_iris +fi diff --git a/cmake_targets/phy_simulators/CMakeLists.txt b/cmake_targets/phy_simulators/CMakeLists.txt index cf68ca4a9d..447e90bcab 100644 --- a/cmake_targets/phy_simulators/CMakeLists.txt +++ b/cmake_targets/phy_simulators/CMakeLists.txt @@ -4,7 +4,6 @@ set ( CMAKE_BUILD_TYPE ) set ( CFLAGS_PROCESSOR_USER "" ) set ( UE_EXPANSION False ) set ( PRE_SCD_THREAD False ) -set ( UESIM_EXPANSION False ) set ( ENABLE_VCD_FIFO False ) set ( RF_BOARD "None") set ( TRANSP_PRO "None") @@ -17,4 +16,5 @@ set ( UE_DEBUG_TRACE False ) set ( UE_TIMING_TRACE False ) set ( USRP_REC_PLAY False ) set ( SKIP_SHARED_LIB_FLAG False ) +set ( PHYSIM True) include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index b8f0125b10..674d4a0cac 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -40,7 +40,15 @@ esac KERNEL_VERSION=$(uname -r | cut -d '.' -f1) KERNEL_MAJOR=$(uname -r | cut -d '.' -f2) -SUDO='sudo -E' +#check if we run inside a container +IS_CONTAINER=`egrep -c "docker|podman|kubepods" /proc/self/cgroup || true` +#sudo is not needed when we are root +if [ "$UID" = 0 ] +then + SUDO='' +else + SUDO='sudo -S -E' +fi ############################### ## echo and family @@ -104,6 +112,10 @@ check_supported_distribution() { "rhel7") return 0 ;; "rhel7.6") return 0 ;; "rhel7.7") return 0 ;; + "rhel7.8") return 0 ;; + "rhel8.2") return 0 ;; + "rhel8.3") return 0 ;; + "rhel8.4") return 0 ;; "centos7") return 0 ;; esac return 1 @@ -241,10 +253,21 @@ install_protobuf_from_source(){ #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner #cd protobuf-2.6.1/ - rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 - wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz - tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $(groups | cut -d" " -f1) --no-same-owner - cd protobuf-3.3.0/ + + if [ $IS_CONTAINER -eq 0 ] + then + rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 + wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner + cd protobuf-3.3.0/ + else + export LD_LIBRARY_PATH=/usr/local/lib #protoc needs to know where toclook for shared libs + rm -rf /tmp/protobuf + git clone --depth=1 --branch=v3.3.0 https://github.com/protocolbuffers/protobuf.git /tmp/protobuf + cd /tmp/protobuf + git submodule update --init --recursive + ./autogen.sh + fi ./configure echo "Compiling protobuf" make -j`nproc` @@ -279,12 +302,12 @@ install_usrp_uhd_driver_from_source(){ uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log " ( - cd /tmp + pushd /tmp echo "Downloading UHD driver" rm -rf /tmp/uhd git clone https://github.com/EttusResearch/uhd.git cd uhd - git checkout tags/v3.13.0.2 + git checkout tags/v4.0.0.0 mkdir -p host/build cd host/build $CMAKE ../ @@ -292,7 +315,9 @@ install_usrp_uhd_driver_from_source(){ make -j`nproc` make test $SUDO make install - $SUDO ldconfig + $SUDO ldconfig -v + popd + rm -rf /tmp/uhd ) >& $uhd_install_log } @@ -324,11 +349,20 @@ check_install_usrp_uhd_driver(){ $SUDO apt-get -y install python python-tk libboost-all-dev libusb-1.0-0-dev $SUDO apt-get -y install libuhd-dev libuhd003 uhd-host elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then - $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake - $SUDO -H pip install requests + if [ $IS_CONTAINER -eq 0 ] + then + $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake + $SUDO -H pip install requests + else + $SUDO $INSTALLER -y install boost boost-devel cmake3 + $SUDO pip3 install mako requests + fi if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then - # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source - $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware + if [ $IS_CONTAINER -eq 0 ] + then + # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source + $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware + fi install_usrp_uhd_driver_from_source else $SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware @@ -750,6 +784,8 @@ check_install_oai_software() { libxml2 \ libxml2-devel \ libxslt-devel \ + ninja-build \ + make \ openssh-clients \ openssh-server \ openssl \ diff --git a/cmake_targets/tools/make_asn1c_includes.sh b/cmake_targets/tools/make_asn1c_includes.sh index cf18f0fa3e..1598678a73 100755 --- a/cmake_targets/tools/make_asn1c_includes.sh +++ b/cmake_targets/tools/make_asn1c_includes.sh @@ -19,6 +19,10 @@ if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then sed -i 's/18446744073709551615))/18446744073709551615U))/g' "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}E-RABUsageReportItem.c sed -i 's/18446744073709551615 }/18446744073709551615U }/g' "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}E-RABUsageReportItem.c fi + if [ "$ASN1C_PREFIX" = "NGAP_" ] ; then + sed -i 's/18446744073709551615))/18446744073709551615U))/g' "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}VolumeTimedReport-Item.c + sed -i 's/18446744073709551615 }/18446744073709551615U }/g' "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}VolumeTimedReport-Item.c + fi fi touch $done_flag diff --git a/common/ran_context.h b/common/ran_context.h index 8262f5dd55..3f57c000a0 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -47,6 +47,7 @@ #include "NwGtpv1uMsg.h" #include "NwGtpv1uPrivate.h" #include "gtpv1u_eNB_defs.h" +#include "gtpv1u_gNB_defs.h" #include "PHY/defs_L1_NB_IoT.h" #include "RRC/LTE/defs_NB_IoT.h" @@ -109,6 +110,8 @@ typedef struct { struct gNB_MAC_INST_s **nrmac; /// GTPu descriptor gtpv1u_data_t *gtpv1u_data_g; + /// NR GTPu descriptor + nr_gtpv1u_data_t *nr_gtpv1u_data_g; /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces struct RU_t_s **ru; /// Mask to indicate fronthaul setup status of RU (hard-limit to 64 RUs) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index f6d57bd791..2340c78bf1 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -445,6 +445,7 @@ int logInit (void) register_log_component("NR_RRC","log",NR_RRC); register_log_component("NR_MAC","log",NR_MAC); register_log_component("NR_PHY","log",NR_PHY); + register_log_component("NGAP","",NGAP); 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 8e74f4148c..d893708a8b 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -148,6 +148,7 @@ extern "C" { #define DEBUG_SECURITY (1<<11) #define DEBUG_NAS (1<<12) #define DEBUG_RLC (1<<13) +#define DEBUG_DLSCH_DECOD (1<<14) #define UE_TIMING (1<<20) @@ -166,6 +167,7 @@ extern "C" { {"SECURITY", DEBUG_SECURITY},\ {"NAS", DEBUG_NAS},\ {"RLC", DEBUG_RLC},\ + {"DLSCH_DECOD", DEBUG_DLSCH_DECOD},\ {"UE_TIMING", UE_TIMING},\ {NULL,-1}\ } @@ -226,6 +228,7 @@ typedef enum { X2AP, M2AP, M3AP, + NGAP, GNB_APP, NR_RRC, NR_MAC, @@ -397,18 +400,21 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int /* define variable only used in LOG macro's */ # define LOG_VAR(A,B) A B # else /* T_TRACER: remove all debugging and tracing messages, except errors */ -# define LOG_I(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)/* */ -# define LOG_W(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ; } while(0)/* */ -# define LOG_E(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ; } while(0)/* */ -# define LOG_D(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ; } while(0)/* */ -# define LOG_T(c, x...) /* */ -# define LOG_DUMPMSG(c, b, s, x...) /* */ +# define LOG_E(c, x...) do { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} while (0) +# define LOG_W(c, x...) do { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} while (0) +# define LOG_I(c, x...) do { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} while (0) +# define LOG_D(c, x...) do { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} while (0) +# define LOG_T(c, x...) do { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} while (0) +# define VLOG(c,l, f, args) do { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ; } while (0) + # define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) -# define LOG_DEBUGFLAG(D) ( 0 ) -# define LOG_DUMPFLAG(D) ( 0 ) +# define LOG_DEBUGFLAG(D) (g_log->dump_mask & D) +# define LOG_DUMPFLAG(D) (g_log->debug_mask & D) +# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ + # define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) -# define LOG_VAR(A,B) +# define LOG_VAR(A,B) A B # endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ #define GCC_NOTUSED __attribute__((unused)) diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 90857d7cd9..bd598b48da 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -814,6 +814,7 @@ static inline unsigned long long int vcd_get_time(void) return (long long unsigned int)((time.tv_nsec - g_time_start.tv_nsec)) + ((long long unsigned int)time.tv_sec - (long long unsigned int)g_time_start.tv_sec) * 1000000000UL; #endif + return 0; } void vcd_signal_dumper_create_header(void) diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index 601465c628..f9f5868260 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -601,11 +601,19 @@ extern int ouput_vcd; #else /* T_TRACER */ +#if ENABLE_VCD #define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT) vcd_signal_dumper_init(aRgUmEnT) #define VCD_SIGNAL_DUMPER_CLOSE() vcd_signal_dumper_close() #define VCD_SIGNAL_DUMPER_CREATE_HEADER() vcd_signal_dumper_create_header() #define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(vAr1,vAr2) vcd_signal_dumper_dump_variable_by_name(vAr1,vAr2) #define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2) vcd_signal_dumper_dump_function_by_name(vAr1,vAr2) +#else +#define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT) +#define VCD_SIGNAL_DUMPER_CLOSE() +#define VCD_SIGNAL_DUMPER_CREATE_HEADER() +#define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(vAr1,vAr2) +#define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2) +#endif #endif /* T_TRACER */ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index d036b40560..06ee5bf12b 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -85,6 +85,10 @@ ID = ENB_PHY_MIB DESC = MIB data GROUP = ALL:PHY:ENB:WIRESHARK FORMAT = int,eNB_ID : int,frame : int,subframe : buffer,data +ID = GNB_PHY_MIB + DESC = NR MIB data + GROUP = ALL:PHY:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data #MAC logs ID = ENB_MAC_UE_DL_SDU @@ -125,12 +129,24 @@ ID = ENB_MAC_UE_DL_PDU_WITH_DATA FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data ID = ENB_MAC_SCHEDULING_REQUEST DESC = MAC scheduling request detected for an UE - GROUP = ALL:MAC:ENB + GROUP = ALL:MAC:ENB:WIRESHARK FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,rnti ID = ENB_MAC_UE_DL_RAR_PDU_WITH_DATA DESC = MAC downlink PDU for an UE GROUP = ALL:MAC:ENB:WIRESHARK FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data +ID = GNB_MAC_DL_PDU_WITH_DATA + DESC = NR MAC downlink PDU for an UE + GROUP = ALL:MAC:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,CC_id : int,rnti : int,frame : int,slot : int,harq_pid : buffer,data +ID = GNB_MAC_UL_PDU_WITH_DATA + DESC = NR MAC uplink PDU for an UE + GROUP = ALL:MAC:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,CC_id : int,rnti : int,frame : int,slot : int,harq_pid : buffer,data +ID = GNB_MAC_DL_RAR_PDU_WITH_DATA + DESC = NR MAC downlink PDU for RAR + GROUP = ALL:MAC:GNB:WIRESHARK + FORMAT = int,gNB_ID : int,CC_id : int,rnti : int,frame : int,slot : int,harq_pid : buffer,data #RLC logs ID = ENB_RLC_DL @@ -384,6 +400,27 @@ ID = LEGACY_S1AP_TRACE GROUP = ALL:LEGACY_S1AP:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_NGAP_INFO + DESC = NGAP legacy logs - info level + GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_NGAP_ERROR + DESC = NGAP legacy logs - error level + GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_NGAP_WARNING + DESC = NGAP legacy logs - warning level + GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_NGAP_DEBUG + DESC = NGAP legacy logs - debug level + GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_NGAP_TRACE + DESC = NGAP legacy logs - trace level + GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_X2AP_INFO DESC = X2AP legacy logs - info level GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_INFO:LEGACY diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index c391a99786..d04f2c317d 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -18,11 +18,14 @@ #define DEFAULT_LIVE_PORT 2021 #define NO_PREAMBLE -1 +#define NO_SR_RNTI -1 typedef struct { int socket; struct sockaddr_in to; OBUF buf; + + /* LTE traces */ /* ul */ int ul_rnti; int ul_frame; @@ -46,6 +49,32 @@ typedef struct { int rar_frame; int rar_subframe; int rar_data; + /* SR */ + int sr_rnti; + int sr_frame; + int sr_subframe; + + /* NR traces */ + /* NR ul */ + int nr_ul_rnti; + int nr_ul_frame; + int nr_ul_slot; + int nr_ul_data; + /* NR dl */ + int nr_dl_rnti; + int nr_dl_frame; + int nr_dl_slot; + int nr_dl_data; + /* NR mib */ + int nr_mib_frame; + int nr_mib_slot; + int nr_mib_data; + /* NR RAR */ + int nr_rar_rnti; + int nr_rar_frame; + int nr_rar_slot; + int nr_rar_data; + /* config */ int no_mib; int no_sib; @@ -56,10 +85,25 @@ typedef struct { /* runtime vars */ int cur_mib; int cur_sib; + + /* hack to report UE id: + * each time we see a rnti, we allocate the next ue_id + * (two separate versions for lte and nr) + */ + int lte_rnti_to_ueid[65536]; + int lte_next_ue_id; + int nr_rnti_to_ueid[65536]; + int nr_next_ue_id; } ev_data; -void trace(ev_data *d, int direction, int rnti_type, int rnti, - int frame, int subframe, void *buf, int bufsize, int preamble) { +/****************************************************************************/ +/* LTE */ +/****************************************************************************/ + +void trace_lte(ev_data *d, int direction, int rnti_type, int rnti, + int frame, int subframe, void *buf, int bufsize, int preamble, + int sr_rnti) +{ ssize_t ret; int fsf; int i; @@ -73,6 +117,18 @@ void trace(ev_data *d, int direction, int rnti_type, int rnti, PUTC(&d->buf, MAC_LTE_RNTI_TAG); PUTC(&d->buf, (rnti>>8) & 255); PUTC(&d->buf, rnti & 255); + + /* put UE id */ + if (rnti < 0 || rnti > 65535) { printf("bad rnti!\n"); exit(1); } + /* if no UE id allocated for this rnti then allocate the next one */ + if (d->lte_rnti_to_ueid[rnti] == -1) { + d->lte_rnti_to_ueid[rnti] = d->lte_next_ue_id; + d->lte_next_ue_id++; + } + + PUTC(&d->buf, MAC_LTE_UEID_TAG); + PUTC(&d->buf, (d->lte_rnti_to_ueid[rnti]>>8) & 255); + PUTC(&d->buf, d->lte_rnti_to_ueid[rnti] & 255); } /* for newer version of wireshark? */ @@ -89,6 +145,25 @@ void trace(ev_data *d, int direction, int rnti_type, int rnti, PUTC(&d->buf, 0); /* rach attempt - always 0 for us (not sure of this) */ } + if (sr_rnti != NO_SR_RNTI) { + PUTC(&d->buf, MAC_LTE_SR_TAG); + PUTC(&d->buf, 0); /* number of items byte 1 */ + PUTC(&d->buf, 1); /* number of items byte 2 */ + + /* put UE id */ + if (sr_rnti < 0 || sr_rnti > 65535) { printf("bad sr rnti!\n"); exit(1); } + /* if no UE id allocated for this rnti then allocate the next one */ + if (d->lte_rnti_to_ueid[sr_rnti] == -1) { + d->lte_rnti_to_ueid[sr_rnti] = d->lte_next_ue_id; + d->lte_next_ue_id++; + } + PUTC(&d->buf, (d->lte_rnti_to_ueid[sr_rnti]>>8) & 255); + PUTC(&d->buf, d->lte_rnti_to_ueid[sr_rnti] & 255); + + PUTC(&d->buf, (sr_rnti>>8) & 255); + PUTC(&d->buf, sr_rnti & 255); + } + PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); for (i = 0; i < bufsize; i++) @@ -100,15 +175,17 @@ void trace(ev_data *d, int direction, int rnti_type, int rnti, if (ret != d->buf.osize) abort(); } -void ul(void *_d, event e) { +void ul(void *_d, event e) +{ ev_data *d = _d; - trace(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i, - e.e[d->ul_frame].i, e.e[d->ul_subframe].i, - e.e[d->ul_data].b, e.e[d->ul_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i, + e.e[d->ul_frame].i, e.e[d->ul_subframe].i, + e.e[d->ul_data].b, e.e[d->ul_data].bsize, + NO_PREAMBLE, NO_SR_RNTI); } -void dl(void *_d, event e) { +void dl(void *_d, event e) +{ ev_data *d = _d; if (e.e[d->dl_rnti].i == 0xffff) { @@ -119,14 +196,15 @@ void dl(void *_d, event e) { d->cur_sib++; } - trace(d, DIRECTION_DOWNLINK, - e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i, - e.e[d->dl_frame].i, e.e[d->dl_subframe].i, - e.e[d->dl_data].b, e.e[d->dl_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_DOWNLINK, + e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i, + e.e[d->dl_frame].i, e.e[d->dl_subframe].i, + e.e[d->dl_data].b, e.e[d->dl_data].bsize, + NO_PREAMBLE, NO_SR_RNTI); } -void mib(void *_d, event e) { +void mib(void *_d, event e) +{ ev_data *d = _d; if (d->no_mib) return; @@ -134,30 +212,163 @@ void mib(void *_d, event e) { if (d->max_mib && d->cur_mib == d->max_mib) return; d->cur_mib++; - trace(d, DIRECTION_DOWNLINK, NO_RNTI, 0, - e.e[d->mib_frame].i, e.e[d->mib_subframe].i, - e.e[d->mib_data].b, e.e[d->mib_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_DOWNLINK, NO_RNTI, 0, + e.e[d->mib_frame].i, e.e[d->mib_subframe].i, + e.e[d->mib_data].b, e.e[d->mib_data].bsize, + NO_PREAMBLE, NO_SR_RNTI); } -void preamble(void *_d, event e) { +void preamble(void *_d, event e) +{ ev_data *d = _d; - trace(d, DIRECTION_UPLINK, NO_RNTI, 0, - e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i, - NULL, 0, - e.e[d->preamble_preamble].i); + trace_lte(d, DIRECTION_UPLINK, NO_RNTI, 0, + e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i, + NULL, 0, + e.e[d->preamble_preamble].i, NO_SR_RNTI); } -void rar(void *_d, event e) { +void rar(void *_d, event e) +{ ev_data *d = _d; - trace(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i, - e.e[d->rar_frame].i, e.e[d->rar_subframe].i, - e.e[d->rar_data].b, e.e[d->rar_data].bsize, - NO_PREAMBLE); + trace_lte(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i, + e.e[d->rar_frame].i, e.e[d->rar_subframe].i, + e.e[d->rar_data].b, e.e[d->rar_data].bsize, + NO_PREAMBLE, NO_SR_RNTI); } +void sr(void *_d, event e) +{ + ev_data *d = _d; + trace_lte(d, DIRECTION_UPLINK, NO_RNTI, 0, + e.e[d->sr_frame].i, e.e[d->sr_subframe].i, + NULL, 0, + NO_PREAMBLE, e.e[d->sr_rnti].i); +} + +/****************************************************************************/ +/* NR */ +/****************************************************************************/ + +#define MAC_NR_START_STRING "mac-nr" + +#define MAC_NR_PAYLOAD_TAG 0x01 +#define MAC_NR_RNTI_TAG 0x02 +#define MAC_NR_UEID_TAG 0x03 +#define MAC_NR_FRAME_SLOT_TAG 0x07 + +#define NR_FDD_RADIO 1 +#define NR_TDD_RADIO 2 + +#define NR_DIRECTION_UPLINK 0 +#define NR_DIRECTION_DOWNLINK 1 + +#define NR_NO_RNTI 0 +#define NR_RA_RNTI 2 +#define NR_C_RNTI 3 + +void trace_nr(ev_data *d, int direction, int rnti_type, int rnti, + int frame, int slot, void *buf, int bufsize, int preamble) +{ + ssize_t ret; + int i; + d->buf.osize = 0; + PUTS(&d->buf, MAC_NR_START_STRING); + PUTC(&d->buf, NR_TDD_RADIO); + PUTC(&d->buf, direction); + PUTC(&d->buf, rnti_type); + + if (rnti_type == NR_C_RNTI || rnti_type == NR_RA_RNTI) { + PUTC(&d->buf, MAC_NR_RNTI_TAG); + PUTC(&d->buf, (rnti>>8) & 255); + PUTC(&d->buf, rnti & 255); + + /* put UE id */ + if (rnti < 0 || rnti > 65535) { printf("bad rnti!\n"); exit(1); } + /* if no UE id allocated for this rnti then allocate the next one */ + if (d->nr_rnti_to_ueid[rnti] == -1) { + d->nr_rnti_to_ueid[rnti] = d->nr_next_ue_id; + d->nr_next_ue_id++; + } + + PUTC(&d->buf, MAC_NR_UEID_TAG); + PUTC(&d->buf, (d->nr_rnti_to_ueid[rnti]>>8) & 255); + PUTC(&d->buf, d->nr_rnti_to_ueid[rnti] & 255); + } + +#if 0 + /* for old versions of wireshark; not sure if correct */ + int fsf = (frame << 4) + slot; + PUTC(&d->buf, 4 /* MAC_NR_FRAME_SUBFRAME_TAG */); + PUTC(&d->buf, (fsf>>8) & 255); + PUTC(&d->buf, fsf & 255); +#else + PUTC(&d->buf, MAC_NR_FRAME_SLOT_TAG); + PUTC(&d->buf, (frame>>8) & 255); + PUTC(&d->buf, frame & 255); + PUTC(&d->buf, (slot>>8) & 255); + PUTC(&d->buf, slot & 255); +#endif + + PUTC(&d->buf, MAC_NR_PAYLOAD_TAG); + + for (i = 0; i < bufsize; i++) + PUTC(&d->buf, ((char *)buf)[i]); + + ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, + (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + + if (ret != d->buf.osize) abort(); +} + +void nr_ul(void *_d, event e) +{ + ev_data *d = _d; + + trace_nr(d, NR_DIRECTION_UPLINK, NR_C_RNTI, e.e[d->nr_ul_rnti].i, + e.e[d->nr_ul_frame].i, e.e[d->nr_ul_slot].i, + e.e[d->nr_ul_data].b, e.e[d->nr_ul_data].bsize, NO_PREAMBLE); +} + +void nr_dl(void *_d, event e) +{ + ev_data *d = _d; + + trace_nr(d, NR_DIRECTION_DOWNLINK, NR_C_RNTI, e.e[d->nr_dl_rnti].i, + e.e[d->nr_dl_frame].i, e.e[d->nr_dl_slot].i, + e.e[d->nr_dl_data].b, e.e[d->nr_dl_data].bsize, NO_PREAMBLE); +} + +void nr_mib(void *_d, event e) +{ + ev_data *d = _d; + + if (d->no_mib) return; + + if (d->max_mib && d->cur_mib == d->max_mib) return; + + d->cur_mib++; + + trace_nr(d, NR_DIRECTION_DOWNLINK, NR_NO_RNTI, 0, + e.e[d->nr_mib_frame].i, e.e[d->nr_mib_slot].i, + e.e[d->nr_mib_data].b, e.e[d->nr_mib_data].bsize, NO_PREAMBLE); +} + +void nr_rar(void *_d, event e) +{ + ev_data *d = _d; + + trace_nr(d, NR_DIRECTION_DOWNLINK, NR_RA_RNTI, e.e[d->nr_rar_rnti].i, + e.e[d->nr_rar_frame].i, e.e[d->nr_rar_slot].i, + e.e[d->nr_rar_data].b, e.e[d->nr_rar_data].bsize, NO_PREAMBLE); +} + +/****************************************************************************/ +/****************************************************************************/ + void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, - int preamble_id, int rar_id) { + int preamble_id, int rar_id, int sr_id, + int nr_ul_id, int nr_dl_id, int nr_mib_id, int nr_rar_id) +{ database_event_format f; int i; d->ul_rnti = -1; @@ -174,10 +385,30 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, d->preamble_frame = -1; d->preamble_subframe = -1; d->preamble_preamble = -1; - d->rar_rnti = -1; - d->rar_frame = -1; - d->rar_subframe = -1; - d->rar_data = -1; + d->rar_rnti = -1; + d->rar_frame = -1; + d->rar_subframe = -1; + d->rar_data = -1; + d->sr_rnti = -1; + d->sr_frame = -1; + d->sr_subframe = -1; + + d->nr_ul_rnti = -1; + d->nr_ul_frame = -1; + d->nr_ul_slot = -1; + d->nr_ul_data = -1; + d->nr_dl_rnti = -1; + d->nr_dl_frame = -1; + d->nr_dl_slot = -1; + d->nr_dl_data = -1; + d->nr_mib_frame = -1; + d->nr_mib_slot = -1; + d->nr_mib_data = -1; + d->nr_rar_rnti = -1; + d->nr_rar_frame = -1; + d->nr_rar_slot = -1; + d->nr_rar_data = -1; + #define G(var_name, var_type, var) \ if (!strcmp(f.name[i], var_name)) { \ if (strcmp(f.type[i], var_type)) goto error; \ @@ -247,6 +478,72 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, if (d->rar_rnti == -1 || d->rar_frame == -1 || d->rar_subframe == -1 || d->rar_data == -1) goto error; + /* sr: rnti, frame, subframe */ + f = get_format(database, sr_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->sr_rnti); + G("frame", "int", d->sr_frame); + G("subframe", "int", d->sr_subframe); + } + + if (d->sr_rnti == -1 || d->sr_frame == -1 || d->sr_subframe == -1) + goto error; + + /* NR ul: rnti, frame, slot, data */ + f = get_format(database, nr_ul_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->nr_ul_rnti); + G("frame", "int", d->nr_ul_frame); + G("slot", "int", d->nr_ul_slot); + G("data", "buffer", d->nr_ul_data); + } + + if (d->nr_ul_rnti == -1 || d->nr_ul_frame == -1 || d->nr_ul_slot == -1 || + d->nr_ul_data == -1) + goto error; + + /* NR dl: rnti, frame, slot, data */ + f = get_format(database, nr_dl_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->nr_dl_rnti); + G("frame", "int", d->nr_dl_frame); + G("slot", "int", d->nr_dl_slot); + G("data", "buffer", d->nr_dl_data); + } + + if (d->nr_dl_rnti == -1 || d->nr_dl_frame == -1 || d->nr_dl_slot == -1 || + d->nr_dl_data == -1) + goto error; + + /* NR MIB: frame, slot, data */ + f = get_format(database, nr_mib_id); + + for (i = 0; i < f.count; i++) { + G("frame", "int", d->nr_mib_frame); + G("slot", "int", d->nr_mib_slot); + G("data", "buffer", d->nr_mib_data); + } + + if (d->nr_mib_frame == -1 || d->nr_mib_slot== -1 || d->nr_mib_data == -1) + goto error; + + /* NR RAR: rnti, frame, slot, data */ + f = get_format(database, nr_rar_id); + + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->nr_rar_rnti); + G("frame", "int", d->nr_rar_frame); + G("slot", "int", d->nr_rar_slot); + G("data", "buffer", d->nr_rar_data); + } + + if (d->nr_rar_rnti == -1 || d->nr_rar_frame == -1 || d->nr_rar_slot == -1 || + d->nr_rar_data == -1) + goto error; + #undef G return; error: @@ -254,7 +551,8 @@ error: abort(); } -void *receiver(void *_d) { +void *receiver(void *_d) +{ ev_data *d = _d; int s; char buf[100000]; @@ -279,7 +577,8 @@ void *receiver(void *_d) { return 0; } -void usage(void) { +void usage(void) +{ printf( "options:\n" " -d this option is mandatory\n" @@ -304,14 +603,17 @@ void usage(void) { exit(1); } -int main(int n, char **v) { +int main(int n, char **v) +{ char *database_filename = NULL; char *input_filename = NULL; void *database; event_handler *h; int in; int i; - int ul_id, dl_id, mib_id = -1, preamble_id, rar_id; + int ul_id, dl_id, mib_id, preamble_id, rar_id; + int nr_ul_id, nr_dl_id, nr_mib_id, nr_rar_id; + int sr_id; ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; @@ -320,6 +622,11 @@ int main(int n, char **v) { int live = 0; memset(&d, 0, sizeof(ev_data)); + for (i = 0; i < 65536; i++) { + d.lte_rnti_to_ueid[i] = -1; + d.nr_rnti_to_ueid[i] = -1; + } + for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); if (!strcmp(v[i], "-d")) { if(i>n-2)usage(); database_filename = v[++i]; continue; } @@ -381,6 +688,12 @@ int main(int n, char **v) { on_off(database, "ENB_PHY_MIB", is_on, 1); on_off(database, "ENB_PHY_INITIATE_RA_PROCEDURE", is_on, 1); on_off(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA", is_on, 1); + on_off(database, "ENB_MAC_SCHEDULING_REQUEST", is_on, 1); + + on_off(database, "GNB_MAC_UL_PDU_WITH_DATA", is_on, 1); + on_off(database, "GNB_MAC_DL_PDU_WITH_DATA", is_on, 1); + on_off(database, "GNB_PHY_MIB", is_on, 1); + on_off(database, "GNB_MAC_DL_RAR_PDU_WITH_DATA", is_on, 1); /* activate selected traces */ if (socket_send(in, &mt, 1) == -1 || @@ -398,12 +711,28 @@ int main(int n, char **v) { mib_id = event_id_from_name(database, "ENB_PHY_MIB"); preamble_id = event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE"); rar_id = event_id_from_name(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA"); - setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id); + sr_id = event_id_from_name(database, "ENB_MAC_SCHEDULING_REQUEST"); + + nr_ul_id = event_id_from_name(database, "GNB_MAC_UL_PDU_WITH_DATA"); + nr_dl_id = event_id_from_name(database, "GNB_MAC_DL_PDU_WITH_DATA"); + nr_mib_id = event_id_from_name(database, "GNB_PHY_MIB"); + nr_rar_id = event_id_from_name(database, "GNB_MAC_DL_RAR_PDU_WITH_DATA"); + + setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id, sr_id, + nr_ul_id, nr_dl_id, nr_mib_id, nr_rar_id); + register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); register_handler_function(h, mib_id, mib, &d); register_handler_function(h, preamble_id, preamble, &d); register_handler_function(h, rar_id, rar, &d); + register_handler_function(h, sr_id, sr, &d); + + register_handler_function(h, nr_ul_id, nr_ul, &d); + register_handler_function(h, nr_dl_id, nr_dl, &d); + register_handler_function(h, nr_mib_id, nr_mib, &d); + register_handler_function(h, nr_rar_id, nr_rar, &d); + d.socket = socket(AF_INET, SOCK_DGRAM, 0); if (d.socket == -1) { @@ -424,8 +753,10 @@ int main(int n, char **v) { if (e.type == -1) break; - if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id || - e.type == preamble_id || e.type == rar_id)) continue; + if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id || + e.type == preamble_id || e.type == rar_id || e.type == sr_id || + e.type == nr_ul_id || e.type == nr_dl_id || + e.type == nr_mib_id || e.type == nr_rar_id)) continue; handle_event(h, e); } diff --git a/common/utils/T/tracer/packet-mac-lte.h b/common/utils/T/tracer/packet-mac-lte.h index 54e6d1a09b..60181987a9 100644 --- a/common/utils/T/tracer/packet-mac-lte.h +++ b/common/utils/T/tracer/packet-mac-lte.h @@ -11,26 +11,7 @@ * * Copyright (C) 2009 Martin Mathieson. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE + * SPDX-License-Identifier: BSD-2-Clause */ #ifndef __COMMON_UTILS_T_TRACER_PACKET_MAC_LTE__H__ @@ -67,9 +48,9 @@ /* and implemented by this dissector, using the definitions */ /* below. A link to an example program showing you how to encode */ /* these headers and send LTE MAC PDUs on a UDP socket is */ -/* provided at https://wiki.wireshark.org/MAC-LTE */ +/* provided at https://wiki.wireshark.org/MAC-LTE */ /* */ -/* A heuristic dissecter (enabled by a preference) will */ +/* A heuristic dissector (enabled by a preference) will */ /* recognise a signature at the beginning of these frames. */ /*****************************************************************/ @@ -126,18 +107,25 @@ MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte), HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */ -#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL 0x0C +#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG 0x0C /* 0 byte */ -#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL 0x0D +#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D /* 0 byte */ -#define MAC_LTE_CE_MODE 0x0E +#define MAC_LTE_CE_MODE_TAG 0x0E /* 1 byte containing mac_lte_ce_mode enum value */ -#define MAC_LTE_NB_MODE 0x0F +#define MAC_LTE_NB_MODE_TAG 0x0F /* 1 byte containing mac_lte_nb_mode enum value */ +#define MAC_LTE_N_UL_RB_TAG 0x10 +/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */ + +#define MAC_LTE_SR_TAG 0x11 +/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */ + + /* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU continues until the end of the frame) */ #define MAC_LTE_PAYLOAD_TAG 0x01 diff --git a/common/utils/asn1_conversions.h b/common/utils/asn1_conversions.h index 050c065d9d..82dca54c08 100644 --- a/common/utils/asn1_conversions.h +++ b/common/utils/asn1_conversions.h @@ -101,11 +101,11 @@ static inline uint64_t BIT_STRING_to_uint64(BIT_STRING_t *asn) { shift = ((asn->size - 1) * 8) - asn->bits_unused; for (index = 0; index < (asn->size - 1); index++) { - result |= asn->buf[index] << shift; + result |= ((uint64_t)asn->buf[index]) << shift; shift -= 8; } - result |= asn->buf[index] >> asn->bits_unused; + result |= ((uint64_t)asn->buf[index]) >> asn->bits_unused; return result; } diff --git a/common/utils/itti_analyzer/ChangeLog b/common/utils/itti_analyzer/ChangeLog deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/common/utils/itti_analyzer/INSTALL b/common/utils/itti_analyzer/INSTALL deleted file mode 100644 index 2099840756..0000000000 --- a/common/utils/itti_analyzer/INSTALL +++ /dev/null @@ -1,370 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, -Inc. - - Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without warranty of any kind. - -Basic Installation -================== - - Briefly, the shell command `./configure && make && make install' -should configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. Some packages provide this -`INSTALL' file but do not implement all of the features documented -below. The lack of an optional feature in a given package is not -necessarily a bug. More recommendations for GNU packages can be found -in *note Makefile Conventions: (standards)Makefile Conventions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - - The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package, generally using the just-built uninstalled binaries. - - 4. Type `make install' to install the programs and any data files and - documentation. When installing into a prefix owned by root, it is - recommended that the package be configured and built as a regular - user, and only the `make install' phase executed with root - privileges. - - 5. Optionally, type `make installcheck' to repeat any self-tests, but - this time using the binaries in their final installed location. - This target does not install anything. Running this target as a - regular user, particularly if the prior `make install' required - root privileges, verifies that the installation completed - correctly. - - 6. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - - 7. Often, you can also type `make uninstall' to remove the installed - files again. In practice, not all packages have tested that - uninstallation works correctly, even though it is required by the - GNU Coding Standards. - - 8. Some packages, particularly those that use Automake, provide `make - distcheck', which can by used by developers to test that all other - targets like `make install' and `make uninstall' work correctly. - This target is generally not run by end users. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. This -is known as a "VPATH" build. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - - On MacOS X 10.5 and later systems, you can create libraries and -executables that work on multiple system types--known as "fat" or -"universal" binaries--by specifying multiple `-arch' options to the -compiler but only a single `-arch' option to the preprocessor. Like -this: - - ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ - CPP="gcc -E" CXXCPP="g++ -E" - - This is not guaranteed to produce working output in all cases, you -may have to build one architecture at a time and combine the results -using the `lipo' tool if you have problems. - -Installation Names -================== - - By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX', where PREFIX must be an -absolute file name. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. In general, the -default for these options is expressed in terms of `${prefix}', so that -specifying just `--prefix' will affect all of the other directory -specifications that were not explicitly provided. - - The most portable way to affect installation locations is to pass the -correct locations to `configure'; however, many packages provide one or -both of the following shortcuts of passing variable assignments to the -`make install' command line to change installation locations without -having to reconfigure or recompile. - - The first method involves providing an override variable for each -affected directory. For example, `make install -prefix=/alternate/directory' will choose an alternate location for all -directory configuration variables that were expressed in terms of -`${prefix}'. Any directories that were specified during `configure', -but not in terms of `${prefix}', must each be overridden at install -time for the entire installation to be relocated. The approach of -makefile variable overrides for each directory variable is required by -the GNU Coding Standards, and ideally causes no recompilation. -However, some platforms have known limitations with the semantics of -shared libraries that end up requiring recompilation when using this -method, particularly noticeable in packages that use GNU Libtool. - - The second method involves providing the `DESTDIR' variable. For -example, `make install DESTDIR=/alternate/directory' will prepend -`/alternate/directory' before all installation names. The approach of -`DESTDIR' overrides is not required by the GNU Coding Standards, and -does not work on platforms that have drive letters. On the other hand, -it does better at avoiding recompilation issues, and works well even -when some directory options were not specified in terms of `${prefix}' -at `configure' time. - -Optional Features -================= - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - - Some packages offer the ability to configure how verbose the -execution of `make' will be. For these packages, running `./configure ---enable-silent-rules' sets the default to minimal output, which can be -overridden with `make V=1'; while running `./configure ---disable-silent-rules' sets the default to verbose, which can be -overridden with `make V=0'. - -Particular systems -================== - - On HP-UX, the default C compiler is not ANSI C compatible. If GNU -CC is not installed, it is recommended to use the following options in -order to use an ANSI C compiler: - - ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" - -and if that doesn't work, install pre-built binaries of GCC for HP-UX. - - HP-UX `make' updates targets which have the same time stamps as -their prerequisites, which makes it generally unusable when shipped -generated files such as `configure' are involved. Use GNU `make' -instead. - - On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot -parse its `' header file. The option `-nodtk' can be used as -a workaround. If GNU CC is not installed, it is therefore recommended -to try - - ./configure CC="cc" - -and if that doesn't work, try - - ./configure CC="cc -nodtk" - - On Solaris, don't put `/usr/ucb' early in your `PATH'. This -directory contains several dysfunctional programs; working variants of -these programs are available in `/usr/bin'. So, if you need `/usr/ucb' -in your `PATH', put it _after_ `/usr/bin'. - - On Haiku, software installed for all users goes in `/boot/common', -not `/usr/local'. It is recommended to use the following options: - - ./configure --prefix=/boot/common - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - - Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: - - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of all of the options to `configure', and exit. - -`--help=short' -`--help=recursive' - Print a summary of the options unique to this package's - `configure', and exit. The `short' variant lists options used - only in the top level, while the `recursive' variant lists options - also present in any nested packages. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--prefix=DIR' - Use DIR as the installation prefix. *note Installation Names:: - for more details, including other options available for fine-tuning - the installation locations. - -`--no-create' -`-n' - Run the configure checks, but stop before creating any output - files. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. diff --git a/common/utils/itti_analyzer/Makefile.am b/common/utils/itti_analyzer/Makefile.am deleted file mode 100644 index b1a371cfe8..0000000000 --- a/common/utils/itti_analyzer/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -AM_CFLAGS = \ - @ADD_CFLAGS@ \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libparser \ - -I$(top_srcdir)/libresolver \ - -I$(top_srcdir)/libbuffers \ - -I$(top_srcdir)/libui - -SUBDIRS = libparser libresolver libbuffers libui . - -itti_analyzer_LDADD = \ - $(top_builddir)/libui/libui.la \ - $(top_builddir)/libparser/libparser.la \ - $(top_builddir)/libresolver/libresolver.la \ - $(top_builddir)/libbuffers/libbuffers.la - -bin_PROGRAMS = itti_analyzer diff --git a/common/utils/itti_analyzer/NEWS b/common/utils/itti_analyzer/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/common/utils/itti_analyzer/README b/common/utils/itti_analyzer/README deleted file mode 100644 index 8ca077a227..0000000000 --- a/common/utils/itti_analyzer/README +++ /dev/null @@ -1,14 +0,0 @@ - -To run itti_analyzer, please perform the following actions: - -1) apt-get install autotools-dev automake libtool - -2) libtoolize - -3) ./autogen.sh - -4) ./configure - -5) make - -6) ./itti_analyzer \ No newline at end of file diff --git a/common/utils/itti_analyzer/autogen.sh b/common/utils/itti_analyzer/autogen.sh deleted file mode 100755 index 6d08b67921..0000000000 --- a/common/utils/itti_analyzer/autogen.sh +++ /dev/null @@ -1,6 +0,0 @@ -#! /bin/sh - -aclocal \ -&& autoheader \ -&& automake --add-missing \ -&& autoconf \ No newline at end of file diff --git a/common/utils/itti_analyzer/common/itti_types.h b/common/utils/itti_analyzer/common/itti_types.h deleted file mode 100644 index d405e48cbd..0000000000 --- a/common/utils/itti_analyzer/common/itti_types.h +++ /dev/null @@ -1,73 +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 - */ - -/** @brief Intertask Interface common types - * Contains type definitions used for generating and parsing ITTI messages. - * @author Laurent Winckel - */ - -#ifndef _ITTI_TYPES_H_ -#define _ITTI_TYPES_H_ - -#include - -#define CHARS_TO_UINT32(c1, c2, c3, c4) (((c4) << 24) | ((c3) << 16) | ((c2) << 8) | (c1)) - -#define MESSAGE_NUMBER_CHAR_FORMAT "%11u" - -/* Intertask message types */ -enum itti_message_types_e -{ - ITTI_DUMP_XML_DEFINITION = CHARS_TO_UINT32 ('\n', 'I', 'x', 'd'), - ITTI_DUMP_XML_DEFINITION_END = CHARS_TO_UINT32 ('i', 'X', 'D', '\n'), - - ITTI_DUMP_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 'm', 's'), - ITTI_DUMP_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'M', 'S', '\n'), - - ITTI_STATISTIC_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 's', 't'), - ITTI_STATISTIC_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'S', 'T', '\n'), - - /* This signal is not meant to be used by remote analyzer */ - ITTI_DUMP_EXIT_SIGNAL = CHARS_TO_UINT32 ('e', 'X', 'I', 'T'), -}; - -typedef uint32_t itti_message_types_t; - -/* Message header is the common part that should never change between - * remote process and this one. - */ -typedef struct { - /* The size of this structure */ - uint32_t message_size; - itti_message_types_t message_type; -} itti_socket_header_t; - -typedef struct { - char message_number_char[12]; /* 9 chars are needed to store an unsigned 32 bits value in decimal, but must be a multiple of 32 bits to avoid alignment issues */ -} itti_signal_header_t; - - -#define INSTANCE_DEFAULT (UINT16_MAX - 1) -#define INSTANCE_ALL (UINT16_MAX) - -typedef uint16_t instance_t; - -#endif diff --git a/common/utils/itti_analyzer/common/rc.h b/common/utils/itti_analyzer/common/rc.h deleted file mode 100644 index 50786f460f..0000000000 --- a/common/utils/itti_analyzer/common/rc.h +++ /dev/null @@ -1,71 +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 - */ - -#include -#include - -#ifndef RC_H_ -#define RC_H_ - -#define RC_OK 0 -#define RC_FAIL -1 -#define RC_BAD_PARAM -2 -#define RC_NULL_POINTER -3 - -static const char * const rc_strings[] = - {"Ok", "fail", "bad parameter", "null pointer"}; - -#define CHECK_FCT(fCT) \ -do { \ - int rET; \ - if ((rET = fCT) != RC_OK) { \ - fprintf(stderr, #fCT" has failed (%s:%d)\n", __FILE__, __LINE__); \ - return rET; \ - } \ -} while(0) - -#define CHECK_FCT_POSIX(fCT) \ -do { \ - if (fCT == -1) { \ - fprintf(stderr, #fCT" has failed (%d:%s) (%s:%d)\n", errno, \ - strerror(errno), __FILE__, __LINE__); \ - return RC_FAIL; \ - } \ -} while(0) - -#define CHECK_FCT_DO(fCT, dO) \ -do { \ - int rET; \ - if ((rET = fCT) != RC_OK) { \ - fprintf(stderr, #fCT" has returned %d (%s:%d)\n", rET, __FILE__, __LINE__); \ - dO; \ - } \ -} while(0) - -#define CHECK_BUFFER(bUFFER) \ -do { \ - if ((bUFFER) == NULL) { \ - fprintf(stderr, #bUFFER" is NULL (%s:%d)\n", __FILE__, __LINE__); \ - return RC_NULL_POINTER; \ - } \ -} while(0) - -#endif /* RC_H_ */ diff --git a/common/utils/itti_analyzer/configure.ac b/common/utils/itti_analyzer/configure.ac deleted file mode 100644 index c6be3e01ab..0000000000 --- a/common/utils/itti_analyzer/configure.ac +++ /dev/null @@ -1,97 +0,0 @@ -AC_PREREQ([2.68]) - -define([svnversion], esyscmd([sh -c "svnversion ..|tr -d '\n'"])) - -AC_DEFINE(SVN_REVISION, "svnversion", [SVN Revision]) - -AC_INIT([itti_analyzer], [0.2.svnversion], [openair_admin@eurecom.fr]) -AC_CANONICAL_BUILD -AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE([1.11 silent-rules]) - -AC_CONFIG_MACRO_DIR([m4]) - -AC_CONFIG_HEADERS([config.h]) - -AM_MAINTAINER_MODE - -AM_SILENT_RULES([yes]) - -AM_PROG_LIBTOOL - -AC_PROG_RANLIB -AC_PROG_CXX - -AC_FUNC_ALLOCA -AC_FUNC_MALLOC -AC_FUNC_REALLOC - -AC_TYPE_SIZE_T -AC_TYPE_SSIZE_T -AC_TYPE_INT8_T -AC_TYPE_INT16_T -AC_TYPE_INT32_T -AC_TYPE_INT64_T -AC_TYPE_UINT8_T -AC_TYPE_UINT16_T -AC_TYPE_UINT32_T -AC_TYPE_UINT64_T - -AC_CHECK_FUNCS([memset]) -AC_CHECK_FUNCS([socket]) -AC_CHECK_FUNCS([strdup]) -AC_CHECK_FUNCS([strerror]) -AC_CHECK_FUNCS([select]) -AC_CHECK_FUNCS([strstr]) - -AC_CHECK_HEADERS([arpa/inet.h]) -AC_CHECK_HEADERS([fcntl.h]) -AC_CHECK_HEADERS([libintl.h]) -AC_CHECK_HEADERS([malloc.h]) -AC_CHECK_HEADERS([stddef.h]) -AC_CHECK_HEADERS([netinet/in.h]) - -AC_CHECK_LIB(m, log10) - -PKG_CHECK_MODULES(XML2, [libxml-2.0 >= 2.7.8], [HAVE_XML2=true], [AC_MSG_ERROR(lixml-2.0 not installed)]) -CFLAGS="$CFLAGS $XML2_CFLAGS" -LIBS="$LIBS $XML2_LIBS" - -AM_PATH_GTK_3_0(3.0.0, [], AC_MSG_ERROR(Requirement not met: gtk >= 3.0.0)) -CFLAGS="$CFLAGS $GTK_CFLAGS" -LIBS="$LIBS $GTK_LIBS" - -dnl Add these flags -CFLAGS="$CFLAGS -Wall" -CFLAGS="$CFLAGS -Wshadow" -CFLAGS="$CFLAGS -Wcast-align" -CFLAGS="$CFLAGS -Wchar-subscripts" -CFLAGS="$CFLAGS -Wmissing-prototypes" -CFLAGS="$CFLAGS -Wmissing-declarations" -CFLAGS="$CFLAGS -Werror=implicit-function-declaration" - -AC_SUBST([AM_CFLAGS]) -AC_SUBST(ADD_CFLAGS) - -dnl *** Autoconf support *** -AC_ARG_ENABLE(autoconf, - [ --disable-autoconf disable automatic generation of configure script ], - enable_autoconf=$enableval, enable_autoconf=yes -) -AC_PATH_PROG(AUTOCONF, autoconf, @echo autoconf not available) -AC_PATH_PROG(AUTOHEADER, autoheader, @echo autoheader not available) -if test -z "$AUTOCONF"; then enable_autoconf=no ; fi -if test -z "$AUTOHEADER"; then enable_autoconf=no ; fi -if test x$enable_autoconf = xyes; then - CONFIGURE_DEPENDS="configure.in aclocal.m4" -fi -AC_SUBST(CONFIGURE_DEPENDS) - -AC_CONFIG_FILES( - libbuffers/Makefile \ - libparser/Makefile \ - libresolver/Makefile \ - libui/Makefile \ - Makefile \ -) -AC_OUTPUT diff --git a/common/utils/itti_analyzer/filters.xml b/common/utils/itti_analyzer/filters.xml deleted file mode 100644 index 7305a2294c..0000000000 --- a/common/utils/itti_analyzer/filters.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/common/utils/itti_analyzer/filters_mme.xml b/common/utils/itti_analyzer/filters_mme.xml deleted file mode 100644 index 7838982613..0000000000 --- a/common/utils/itti_analyzer/filters_mme.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/common/utils/itti_analyzer/filters_ue_enb.xml b/common/utils/itti_analyzer/filters_ue_enb.xml deleted file mode 100644 index 77859d20b6..0000000000 --- a/common/utils/itti_analyzer/filters_ue_enb.xml +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/common/utils/itti_analyzer/itti_analyzer.c b/common/utils/itti_analyzer/itti_analyzer.c deleted file mode 100644 index d87deb46e2..0000000000 --- a/common/utils/itti_analyzer/itti_analyzer.c +++ /dev/null @@ -1,145 +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 - */ - -#include -#include -#include -#include - -#include - -#include - -#include "xml_parse.h" -#include "resolvers.h" -#include "locate_root.h" -#include "file.h" -#include "ui_main_screen.h" - -#include "rc.h" - -#define G_LOG_LEVELS (G_LOG_LEVEL_ERROR | \ - G_LOG_LEVEL_CRITICAL | \ - G_LOG_LEVEL_WARNING | \ - G_LOG_LEVEL_MESSAGE | \ - G_LOG_LEVEL_INFO | \ - G_LOG_LEVEL_DEBUG) - -int debug_buffers = 1; -int debug_parser = 0; - -static void console_log_handler(const char *log_domain, GLogLevelFlags log_level, - const char *message, gpointer user_data) -{ - GLogLevelFlags domain_log_level = (GLogLevelFlags) user_data; - time_t curr; - struct tm *today; - const char *level; - - if (ui_main_data.log_flags & domain_log_level & log_level) - { - switch (log_level & G_LOG_LEVEL_MASK) - { - case G_LOG_LEVEL_ERROR: - level = "Err "; - break; - case G_LOG_LEVEL_CRITICAL: - level = "Crit"; - break; - case G_LOG_LEVEL_WARNING: - level = "Warn"; - break; - case G_LOG_LEVEL_MESSAGE: - level = "Msg "; - break; - case G_LOG_LEVEL_INFO: - level = "Info"; - break; - case G_LOG_LEVEL_DEBUG: - level = "Dbg "; - break; - default: - fprintf(stderr, "unknown log_level %u\n", log_level); - level = NULL; - g_assert_not_reached(); - break; - } - - /* create a "timestamp" */ - time(&curr); - today = localtime(&curr); - - fprintf(stderr, "%02u:%02u:%02u %-9s %s %s\n", today->tm_hour, today->tm_min, today->tm_sec, - log_domain != NULL ? log_domain : "", level, message); - } -} - -int main(int argc, char *argv[]) -{ - int ret = 0; - - GLogLevelFlags log_flags; - - log_flags = (GLogLevelFlags) - (G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | - G_LOG_LEVEL_INFO | - G_LOG_LEVEL_DEBUG); - - /* This initialize the library and check potential ABI mismatches - * between the version it was compiled for and the actual shared - * library used. - */ - LIBXML_TEST_VERSION; - xmlInitParser(); - - /* Initialize the widget set */ - gtk_init(&argc, &argv); - - /* Parse command line options */ - ui_gtk_parse_arg (argc, argv); - - /* Set log handlers: - * Domain, Levels, Handler, Domain enabled levels */ - g_log_set_handler( NULL, log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS)); - g_log_set_handler("BUFFERS", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG)))); - g_log_set_handler("PARSER", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG)))); - g_log_set_handler("RESOLVER", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG)))); - g_log_set_handler("UI", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG)))); - g_log_set_handler("UI_CB", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS)); - g_log_set_handler("UI_FILTER", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG)))); - g_log_set_handler("UI_INTER", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS)); - g_log_set_handler("UI_TREE", log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG)))); - - CHECK_FCT(ui_gtk_initialize(argc, argv)); - - /* Enter the main event loop, and wait for user interaction */ - gtk_main (); - - /* Free the global variables that may - * have been allocated by the parser. - */ - xmlCleanupParser (); - - return ret; -} diff --git a/common/utils/itti_analyzer/libbuffers/Makefile.am b/common/utils/itti_analyzer/libbuffers/Makefile.am deleted file mode 100644 index 7af612e5e7..0000000000 --- a/common/utils/itti_analyzer/libbuffers/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -AM_CFLAGS = \ - @ADD_CFLAGS@ \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libparser \ - -I$(top_srcdir)/libui - -noinst_LTLIBRARIES = libbuffers.la - -libbuffers_la_LDFLAGS = -all-static -libbuffers_la_SOURCES = \ - buffers.c buffers.h \ - file.c file.h \ - socket.c socket.h diff --git a/common/utils/itti_analyzer/libbuffers/buffers.c b/common/utils/itti_analyzer/libbuffers/buffers.c deleted file mode 100644 index 870c9cd40a..0000000000 --- a/common/utils/itti_analyzer/libbuffers/buffers.c +++ /dev/null @@ -1,241 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("BUFFERS") - -#include - -#include "rc.h" -#include "buffers.h" - -extern int debug_buffers; - -static -int buffer_fetch(buffer_t *buffer, uint32_t offset, int size, void *value); - -/* Try to fetch 8 bits unsigned from the buffer */ -uint8_t buffer_get_uint8_t(buffer_t *buffer, uint32_t offset) -{ - uint8_t value; - - buffer_fetch(buffer, offset, 1, &value); - - return value; -} - -/* Try to fetch 16 bits unsigned from the buffer */ -uint16_t buffer_get_uint16_t(buffer_t *buffer, uint32_t offset) -{ - uint16_t value; - - buffer_fetch(buffer, offset, 2, &value); - - return value; -} - -/* Try to fetch 32 bits unsigned from the buffer */ -uint32_t buffer_get_uint32_t(buffer_t *buffer, uint32_t offset) -{ - uint32_t value; - - buffer_fetch(buffer, offset, 4, &value); - - return value; -} - -/* Try to fetch 64 bits unsigned from the buffer */ -uint64_t buffer_get_uint64_t(buffer_t *buffer, uint32_t offset) -{ - uint64_t value; - - buffer_fetch(buffer, offset, 8, &value); - - return value; -} - -static -int buffer_fetch(buffer_t *buffer, uint32_t offset, int size, void *value) -{ - if (buffer == NULL || value == NULL) - return -1; - if (size <= 0) - return -1; - - if (buffer->size_bytes < ((offset >> 3) + size)) { - g_warning("Not enough data to fetch"); - return -1; - } - - memcpy(value, &buffer->data[offset >> 3], size); - buffer->buffer_current = &buffer->data[(offset >> 3) + size]; - - return 0; -} - -int buffer_fetch_nbytes(buffer_t *buffer, uint32_t offset, int n_bytes, uint8_t *value) -{ - if (buffer->size_bytes < ((offset >> 3) + n_bytes)) { - g_warning("Not enough data to fetch"); - return -1; - } - memcpy(&value[0], &buffer->data[offset >> 3], n_bytes); - - return 0; -} - -int buffer_fetch_bits(buffer_t *buffer, uint32_t offset, int nbits, uint32_t *value) -{ - uint32_t temp = 0; - int i; - - if (buffer == NULL || value == NULL) - return RC_BAD_PARAM; - - /* We cannot fetch more than 32 bits */ - if (nbits > 32) - return RC_BAD_PARAM; - - for (i = 0; i < nbits; i++) - { - temp |= ((buffer->data[(offset + i) / 8] >> ((offset + i) % 8)) & 1) << i; - } - - *value = temp; - - return RC_OK; -} - -/** - * @brief Create a new buffer from data - * @param buffer caller reference where created buffer will be stored - * @param data Data to attach to the new buffer - * @param length Length of data buffer - * @param data_static flag that indicates if data pointer has been statically (= 0) or not (!= 0) - */ -int buffer_new_from_data(buffer_t **buffer, uint8_t *data, const uint32_t length, - int data_static) -{ - buffer_t *new; - - if (!buffer) - return RC_BAD_PARAM; - - new = malloc(sizeof(buffer_t)); - - new->size_bytes = length; - if (data && length > 0) { - if (data_static == 0) { - new->data = malloc(sizeof(uint8_t) * new->size_bytes); - memcpy(new->data, data, new->size_bytes); - } else { - new->data = data; - } - new->buffer_current = &new->data[0]; - } else { - new->buffer_current = NULL; - } - - *buffer = new; - - return 0; -} - -#define INDENTED(fILE, x, y) \ -do { \ - int indentation = x; \ - while(indentation--) fprintf(fILE, " "); \ - y; \ -} while(0) - -#define INDENT_BREAK 20 - -void buffer_dump(buffer_t *buffer, FILE *to) -{ - FILE *file = to; - uint32_t i; - - if (!buffer) - return; - if (!to) - to = stdout; - - fprintf(file, "\n"); - INDENTED(file, 4, fprintf(file, "%u\n", buffer->size_bytes)); - INDENTED(file, 4, fprintf(file, "\n")); - for (i = 0; i < buffer->size_bytes; i++) - { - if ((i % INDENT_BREAK) == 0) - fprintf(file, " "); - fprintf(file, "0x%02x ", buffer->data[i]); - if ((i % INDENT_BREAK) == (INDENT_BREAK - 1)) - fprintf(file, "\n"); - } - if ((i % INDENT_BREAK) != (INDENT_BREAK - 1)) - fprintf(file, "\n"); - INDENTED(file, 4, fprintf(file, "\n")); - fprintf(file, "\n"); -} - -int buffer_append_data(buffer_t *buffer, const uint8_t *data, const uint32_t length) -{ - if (!buffer) - return -1; - - if (data && length > 0) { - if (!buffer->data) { - buffer->size_bytes = length; - buffer->data = malloc(sizeof(uint8_t) * buffer->size_bytes); - memcpy(buffer->data, data, buffer->size_bytes); - } else { - buffer->data = realloc(buffer->data, sizeof(uint8_t) * (buffer->size_bytes + length)); - memcpy(&buffer->data[buffer->size_bytes], data, length); - buffer->size_bytes += length; - } - buffer->buffer_current = &buffer->data[0]; - } - - return 0; -} - -int buffer_has_enouch_data(buffer_t *buffer, uint32_t offset, uint32_t to_get) -{ - int underflow; - if (!buffer) - return -1; - underflow = (buffer->size_bytes >= ((offset + to_get) / 8)) ? 0 : -1; - if (underflow && debug_buffers) - g_warning("Detected Underflow offset %u, to_get %u, buffer size %u\n", - offset, to_get, buffer->size_bytes); - return underflow; -} - -void *buffer_at_offset(buffer_t *buffer, uint32_t offset) -{ -// if (buffer_has_enouch_data(buffer, 0, offset) != 0) { -// return NULL; -// } - return &buffer->data[offset / 8]; -} diff --git a/common/utils/itti_analyzer/libbuffers/buffers.h b/common/utils/itti_analyzer/libbuffers/buffers.h deleted file mode 100644 index 34ecb355ab..0000000000 --- a/common/utils/itti_analyzer/libbuffers/buffers.h +++ /dev/null @@ -1,66 +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 - */ - -#include - -#ifndef BUFFERS_H_ -#define BUFFERS_H_ - -typedef struct buffer_s { - /* The size in bytes as read from socket */ - uint32_t size_bytes; - - /* Current position */ - uint8_t *buffer_current; - - /* The complete data */ - uint8_t *data; - - /* The message number as read from socket */ - uint32_t message_number; - - uint32_t message_id; -} buffer_t; - -uint8_t buffer_get_uint8_t(buffer_t *buffer, uint32_t offset); - -uint16_t buffer_get_uint16_t(buffer_t *buffer, uint32_t offset); - -uint32_t buffer_get_uint32_t(buffer_t *buffer, uint32_t offset); - -uint64_t buffer_get_uint64_t(buffer_t *buffer, uint32_t offset); - -int buffer_fetch_bits(buffer_t *buffer, uint32_t offset, int nbits, uint32_t *value); - -int buffer_fetch_nbytes(buffer_t *buffer, uint32_t offset, int n_bytes, uint8_t *value); - -void buffer_dump(buffer_t *buffer, FILE *to); - -int buffer_append_data(buffer_t *buffer, const uint8_t *data, const uint32_t length); - -int buffer_new_from_data(buffer_t **buffer, uint8_t *data, const uint32_t length, - int data_static); - -int buffer_has_enouch_data(buffer_t *buffer, uint32_t offset, uint32_t to_get); - -void *buffer_at_offset(buffer_t *buffer, uint32_t offset); - -#endif /* BUFFERS_H_ */ diff --git a/common/utils/itti_analyzer/libbuffers/file.c b/common/utils/itti_analyzer/libbuffers/file.c deleted file mode 100644 index 291bf2d216..0000000000 --- a/common/utils/itti_analyzer/libbuffers/file.c +++ /dev/null @@ -1,75 +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 - */ - -#include -#include -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("BUFFERS") - -#include - -#include "rc.h" -#include "buffers.h" -#include "file.h" - -#define READ_BUFFER_SIZE 1024 - -int file_read_dump(buffer_t **buffer, const char *filename) -{ - int fd = -1; - buffer_t *new_buf = NULL; - uint8_t data[READ_BUFFER_SIZE]; - ssize_t current_read; - - if (!filename) - return RC_BAD_PARAM; - - if ((fd = open(filename, O_RDONLY)) == -1) { - g_warning("Cannot open %s for reading, returned %d:%s\n", - filename, errno, strerror(errno)); - return RC_FAIL; - } - - CHECK_FCT(buffer_new_from_data(&new_buf, NULL, 0, 0)); - - do { - current_read = read(fd, data, READ_BUFFER_SIZE); - if (current_read == -1) - { - g_warning("Failed to read data from file, returned %d:%s\n", - errno, strerror(errno)); - return RC_FAIL; - } - CHECK_FCT(buffer_append_data(new_buf, data, current_read)); - } while(current_read == READ_BUFFER_SIZE); - - *buffer = new_buf; - - buffer_dump(new_buf, stdout); - - close(fd); - - return RC_OK; -} diff --git a/common/utils/itti_analyzer/libbuffers/socket.c b/common/utils/itti_analyzer/libbuffers/socket.c deleted file mode 100644 index f732af70ec..0000000000 --- a/common/utils/itti_analyzer/libbuffers/socket.c +++ /dev/null @@ -1,444 +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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("BUFFERS") - -#include - -#include "logs.h" -#include "itti_types.h" -#include "rc.h" - -#include "ui_interface.h" -#include "ui_notifications.h" -#include "ui_notif_dlg.h" - -#include "socket.h" -#include "buffers.h" - -#include "xml_parse.h" - -/* Retry connection after 100 ms */ -#define SOCKET_US_BEFORE_CONNECT_RETRY (100 * 1000) -/* About 10 minutes time-out for connecting to peer */ -#define SOCKET_NB_CONNECT_RETRY ((10 * 60 * 1000 * 1000) / SOCKET_US_BEFORE_CONNECT_RETRY) - -#define SOCKET_NB_SIGNALS_BEFORE_SIGNALLING 10 -#define SOCKET_MS_BEFORE_SIGNALLING 100 - -gboolean socket_abort_connection = FALSE; - -void *socket_thread_fct(void *arg); - -static ssize_t socket_read_data(socket_data_t *socket_data, void *buffer, size_t size, int flags) -{ - ssize_t recv_ret; - - recv_ret = recv(socket_data->sd, buffer, size, flags); - if (recv_ret == -1) { - /* Failure case */ - switch (errno) { -// case EWOULDBLOCK: - case EAGAIN: - return -1; - default: - g_info("recv failed: %s", g_strerror(errno)); - pthread_exit(NULL); - break; - } - } else if (recv_ret == 0) { - /* We lost the connection with other peer or shutdown asked */ - ui_pipe_write_message(socket_data->pipe_fd, - UI_PIPE_CONNECTION_LOST, NULL, 0); - free(socket_data->ip_address); - free(socket_data); - pthread_exit(NULL); - } - - return recv_ret; -} - -static void socket_notify_gui_update(socket_data_t *socket_data) -{ - pipe_new_signals_list_message_t pipe_signal_list_message; - - pipe_signal_list_message.signal_list = socket_data->signal_list; - - socket_data->signal_list = NULL; - socket_data->nb_signals_since_last_update = 0; - - /* Send an update notification */ - ui_pipe_write_message(socket_data->pipe_fd, - UI_PIPE_UPDATE_SIGNAL_LIST, &pipe_signal_list_message, - sizeof(pipe_signal_list_message)); - - /* Acquire the last data notification */ - socket_data->last_data_notification = g_get_monotonic_time(); -} - -static int socket_read_itti_message(socket_data_t *socket_data, - itti_socket_header_t *message_header) -{ - itti_signal_header_t itti_signal_header; - buffer_t *buffer; - uint8_t *data; - size_t data_length; - ssize_t data_read = 0; - ssize_t total_data_read = 0; - - g_assert(message_header != NULL); - - g_debug("Attempting to read signal header from socket"); - - /* Read the sub-header of signal */ - while (data_read != sizeof(itti_signal_header_t)) { - data_read = socket_read_data(socket_data, &itti_signal_header, - sizeof(itti_signal_header_t), 0); - } - - data_length = message_header->message_size - sizeof(itti_socket_header_t) - sizeof(itti_signal_header_t); - data = malloc(sizeof(uint8_t) * data_length); - - while (total_data_read < data_length) { - data_read = socket_read_data(socket_data, &data[total_data_read], - data_length - total_data_read, 0); - /* We are waiting for data */ - if (data_read < 0) { - usleep(10); - } else { - total_data_read += data_read; - } - } - - /* Create the new buffer */ - if (buffer_new_from_data(&buffer, data, data_length - sizeof(itti_message_types_t), 1) != RC_OK) { - g_error("Failed to create new buffer"); - g_assert_not_reached(); - } - - sscanf (itti_signal_header.message_number_char, MESSAGE_NUMBER_CHAR_FORMAT, &buffer->message_number); -// buffer_dump(buffer, stdout); - - /* Update the number of signals received since last GUI update */ - socket_data->nb_signals_since_last_update++; - - socket_data->signal_list = g_list_append(socket_data->signal_list, (gpointer)buffer); - - if (socket_data->nb_signals_since_last_update >= SOCKET_NB_SIGNALS_BEFORE_SIGNALLING) { - socket_notify_gui_update(socket_data); - } - - g_debug("Successfully read new signal %u from socket", buffer->message_number); - - return total_data_read + sizeof(itti_signal_header); -} - -static int socket_read_xml_definition(socket_data_t *socket_data, - itti_socket_header_t *message_header) -{ - ssize_t data_read; - ssize_t total_data_read = 0; - char *xml_definition; - size_t xml_definition_length; - pipe_xml_definition_message_t pipe_xml_definition_message; - - xml_definition_length = message_header->message_size - sizeof(*message_header); - xml_definition = malloc(xml_definition_length * sizeof(char)); - - g_debug("Attempting to read XML definition of size %zu from socket", - xml_definition_length); - - /* XML definition is a long message... so function may take some time */ - - do { - data_read = socket_read_data(socket_data, &xml_definition[total_data_read], - xml_definition_length - total_data_read, 0); - - /* We are waiting for data */ - if (data_read < 0) { - usleep(10); - } else { - total_data_read += data_read; - } - } while (total_data_read != xml_definition_length); - - pipe_xml_definition_message.xml_definition = xml_definition; - pipe_xml_definition_message.xml_definition_length = xml_definition_length - sizeof(itti_message_types_t); - - g_debug("Received XML definition of size %zu, effectively read %zu bytes", - xml_definition_length, total_data_read); - - ui_pipe_write_message(socket_data->pipe_fd, UI_PIPE_XML_DEFINITION, - &pipe_xml_definition_message, sizeof(pipe_xml_definition_message)); - - return total_data_read; -} - -static int socket_read(socket_data_t *socket_data) -{ - int ret = 0; - itti_socket_header_t message_header; - - while (ret >= 0) { - ret = socket_read_data(socket_data, &message_header, sizeof(message_header), 0); - - if (ret == -1) { - return 0; - } - - switch(message_header.message_type) { - case ITTI_DUMP_XML_DEFINITION: - socket_read_xml_definition(socket_data, &message_header); - break; - - case ITTI_DUMP_MESSAGE_TYPE: - socket_read_itti_message(socket_data, &message_header); - break; - - case ITTI_STATISTIC_MESSAGE_TYPE: - default: - g_warning("Received unknow (or not implemented) message from socket type: %d", - message_header.message_type); - break; - } - } - - return 0; -} - -static int socket_handle_disconnect_evt(socket_data_t *socket_data) -{ - /* Send shutdown to remote host */ - CHECK_FCT_POSIX(shutdown(socket_data->sd, SHUT_RDWR)); - /* Close file descriptor */ - CHECK_FCT_POSIX(close(socket_data->sd)); - - socket_data->sd = -1; - - /* Close pipe */ - close(socket_data->pipe_fd); - - /* Leaving the thread */ - pthread_exit(NULL); - - return 0; -} - -static int pipe_read_message(socket_data_t *socket_data) -{ - pipe_input_header_t input_header; - uint8_t *input_data = NULL; - size_t input_data_length = 0; - - /* Read the header */ - if (read(socket_data->pipe_fd, &input_header, sizeof(input_header)) < 0) { - g_warning("Failed to read from pipe %d: %s", socket_data->pipe_fd, - g_strerror(errno)); - return -1; - } - - input_data_length = input_header.message_size - sizeof(input_header); - - /* Checking for non-header part */ - if (input_data_length > 0) { - input_data = malloc(sizeof(uint8_t) * input_data_length); - - if (read(socket_data->pipe_fd, input_data, input_data_length) < 0) { - g_warning("Failed to read from pipe %d: %s", socket_data->pipe_fd, - g_strerror(errno)); - return -1; - } - } - - switch (input_header.message_type) { - case UI_PIPE_DISCONNECT_EVT: - return socket_handle_disconnect_evt(socket_data); - default: - g_warning("[socket] Unhandled message type %u", input_header.message_type); - g_assert_not_reached(); - } - return 0; -} - -void *socket_thread_fct(void *arg) -{ - int ret; - struct sockaddr_in si_me; - socket_data_t *socket_data; - int retry = SOCKET_NB_CONNECT_RETRY; - - /* master file descriptor list */ - fd_set master_fds; - /* temp file descriptor list for select() */ - fd_set read_fds; - int fd_max = 0; - struct timeval tv; - - socket_data = (socket_data_t *)arg; - - g_assert(socket_data != NULL); - - /* Preparing the socket */ - if ((socket_data->sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - g_warning("socket failed: %s", g_strerror(errno)); - free(socket_data->ip_address); - free(socket_data); - pthread_exit(NULL); - } - memset((void *)&si_me, 0, sizeof(si_me)); - - si_me.sin_family = AF_INET; - si_me.sin_port = htons(socket_data->port); - if (inet_aton(socket_data->ip_address, &si_me.sin_addr) == 0) { - g_warning("inet_aton() failed\n"); - free(socket_data->ip_address); - free(socket_data); - pthread_exit(NULL); - } - - /* clear the master and temp sets */ - FD_ZERO(&master_fds); - FD_ZERO(&read_fds); - - /* Add the GUI pipe to the list of sockets to monitor */ - FD_SET(socket_data->pipe_fd, &master_fds); - - /* Add the client socket to the list of sockets to monitor */ - FD_SET(socket_data->sd, &master_fds); - - /* Update the fd_max with the MAX of socket/pipe */ - fd_max = MAX(socket_data->pipe_fd, socket_data->sd); - - /* Setup the timeout for select. - * When a timeout is caught, check for new notifications to send to GUI. - */ - tv.tv_sec = 0; - tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING; - - do { - /* Connecting to remote peer */ - ret = connect(socket_data->sd, (struct sockaddr *) &si_me, sizeof(struct sockaddr_in)); - if (ret < 0) { - if ((socket_abort_connection) || (retry < 0)) { - if (retry < 0) { - g_warning("Failed to connect to peer %s:%d", socket_data->ip_address, socket_data->port); - ui_pipe_write_message(socket_data->pipe_fd, UI_PIPE_CONNECTION_FAILED, NULL, 0); - } - free(socket_data->ip_address); - free(socket_data); - socket_abort_connection = FALSE; - /* Quit the thread */ - pthread_exit(NULL); - } - usleep(SOCKET_US_BEFORE_CONNECT_RETRY); - retry--; - } - } while (ret < 0); - - /* Set the socket as non-blocking */ - fcntl(socket_data->sd, F_SETFL, O_NONBLOCK); - - while (1) { - memcpy(&read_fds, &master_fds, sizeof(master_fds)); - - ret = select(fd_max + 1, &read_fds, NULL, NULL, &tv); - if (ret < 0) { - g_warning("Error in select: %s", g_strerror(errno)); - free(socket_data->ip_address); - free(socket_data); - /* Quit the thread */ - pthread_exit(NULL); - } else if (ret == 0) { - /* Timeout for select: check if there is new incoming messages - * since last GUI update - */ - if (socket_data->nb_signals_since_last_update > 0) { - g_debug("Timout on select and data new signal in list"); - g_debug("-> notify GUI"); - socket_notify_gui_update(socket_data); - } - - /* Reset the timeval to the max value */ - tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING; - } - - /* Checking if there is data to read from the pipe */ - if (FD_ISSET(socket_data->pipe_fd, &read_fds)) { - FD_CLR(socket_data->pipe_fd, &read_fds); - pipe_read_message(socket_data); - } - - /* Checking if there is data to read from the socket */ - if (FD_ISSET(socket_data->sd, &read_fds)) { - FD_CLR(socket_data->sd, &read_fds); - socket_read(socket_data); - - /* Update the timeout of select if there is data not notify to GUI */ - if (socket_data->nb_signals_since_last_update > 0) { - gint64 current_time; - - current_time = g_get_monotonic_time(); - - if ((current_time - socket_data->last_data_notification) > SOCKET_MS_BEFORE_SIGNALLING) { - socket_notify_gui_update(socket_data); - tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING; - } else { - /* Update tv */ - tv.tv_usec = (1000 * SOCKET_MS_BEFORE_SIGNALLING) - (current_time - socket_data->last_data_notification); - } - } - } - } - - return NULL; -} - -int socket_connect_to_remote_host(const char *remote_ip, const uint16_t port, - int pipe_fd) -{ - socket_data_t *socket_data; - - socket_data = calloc(1, sizeof(*socket_data)); - - socket_data->ip_address = strdup(remote_ip); - - socket_data->pipe_fd = pipe_fd; - socket_data->port = port; - socket_data->sd = -1; - - if (pthread_create(&socket_data->thread, NULL, socket_thread_fct, socket_data) != 0) { - g_warning("Failed to create thread %d:%s", errno, strerror(errno)); - free(socket_data->ip_address); - free(socket_data); - return RC_FAIL; - } - - return RC_OK; -} diff --git a/common/utils/itti_analyzer/libparser/Makefile.am b/common/utils/itti_analyzer/libparser/Makefile.am deleted file mode 100644 index bf80db2867..0000000000 --- a/common/utils/itti_analyzer/libparser/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -AM_CFLAGS = \ - @ADD_CFLAGS@ \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libbuffers \ - -I$(top_srcdir)/libui - -noinst_LTLIBRARIES = libparser.la - -libparser_la_LDFLAGS = -all-static -libparser_la_SOURCES = \ - xml_parse.c \ - array_type.c array_type.h \ - enum_type.c enum_type.h \ - enum_value_type.c enum_value_type.h \ - file_type.c file_type.h \ - field_type.c field_type.h \ - fundamental_type.c fundamental_type.h \ - pointer_type.h pointer_type.c \ - reference_type.c reference_type.h \ - struct_type.c struct_type.h \ - typedef_type.c typedef_type.h \ - types.h types.c \ - union_type.c union_type.h diff --git a/common/utils/itti_analyzer/libparser/array_type.c b/common/utils/itti_analyzer/libparser/array_type.c deleted file mode 100644 index 1d9f741281..0000000000 --- a/common/utils/itti_analyzer/libparser/array_type.c +++ /dev/null @@ -1,180 +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 - */ - -#include -#include -#include -#include -#include - -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "array_type.h" -#include "fundamental_type.h" -#include "ui_interface.h" - -int array_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - types_t *type_child; - int length = 0; - char cbuf[50]; - - DISPLAY_PARSE_INFO("array", type->name, offset, parent_offset); - - /* Ignore TYPEDEF children */ - for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; - type_child = type_child->child) { - } - - if (type->name) { - INDENTED(stdout, indent, fprintf(stdout, "<%s>\n", type->name)); - } - if (type->child != NULL) { - int items = type->size / type_child->size; - int i; - int zero_counter = 0; - gboolean is_string = FALSE; - char *string; - int nb_digits = 0; - - /* Factorizes trailing 0 */ - if ((items > 1) && (type_child->type == TYPE_FUNDAMENTAL)) - { - for (i = items - 1; i >= 0; i--) - { - if (fundamental_read_from_buffer(type_child, buffer, parent_offset, offset + i * type_child->size) == 0) - { - zero_counter ++; - } - else - { - break; - } - } - - /* Check if this is an array of 8 bits items and if at least the firsts ones are not null */ - if ((type_child->size == 8) && (zero_counter >= 1) && ((items - zero_counter) >= 2)) - { - int end = items - zero_counter; - - /* check if this is a printable string */ - is_string = TRUE; - string = malloc(end + 1); - - for (i = 0; i < end; i++) - { - string[i] = fundamental_read_from_buffer(type_child, buffer, parent_offset, offset + i * type_child->size); - if (isprint(string[i]) == 0) - { - /* This is not a printable string */ - is_string = FALSE; - break; - } - } - - if (is_string) - { - string[i] = '\0'; - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "[0 .. %d] \"%s\"\n", end - 1, string)); - ui_set_signal_text_cb(user_data, cbuf, length); - } - } - - /* Do not factorize if there is only one null item */ - if (zero_counter <= 1) - { - zero_counter = 0; - } - } - - if (is_string == FALSE) - { - nb_digits = log10(items - zero_counter) + 1; - - for (i = 0; i < (items - zero_counter); i++) - { - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "[%*d] ", nb_digits, i)); - ui_set_signal_text_cb(user_data, cbuf, length); - - type->child->type_dissect_from_buffer ( - type->child, ui_set_signal_text_cb, user_data, buffer, parent_offset, - offset + i * type_child->size, indent, - FALSE); - } - if (zero_counter > 0) - { - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "[%d .. %d] ", i, items -1)); - ui_set_signal_text_cb(user_data, cbuf, length); - - type->child->type_dissect_from_buffer ( - type->child, ui_set_signal_text_cb, user_data, - buffer, parent_offset, offset + i * type_child->size, indent, FALSE); - } - } - } - if (type->name) { - INDENTED(stdout, indent, fprintf(stdout, "\n", type->name)); - } - - return 0; -} - -int array_type_file_print(types_t *type, int indent, FILE *file) { - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Min ........: %d\n", type->min)); - INDENTED(file, indent+4, fprintf(file, "Max ........: %d\n", type->max)); - INDENTED(file, indent+4, fprintf(file, "Type .......: %d\n", type->type_xml)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - if (type->file_ref != NULL) - type->file_ref->type_file_print (type->file_ref, indent + 4, file); - if (type->child != NULL) - type->child->type_file_print (type->child, indent + 4, file); - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int array_type_hr_display(types_t *type, int indent) { - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Min ........: %d\n", type->min)); - INDENTED(stdout, indent+4, printf("Max ........: %d\n", type->max)); - INDENTED(stdout, indent+4, printf("Type .......: %d\n", type->type_xml)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display (type->file_ref, indent + 4); - if (type->child != NULL) - type->child->type_hr_display (type->child, indent + 4); - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/enum_type.c b/common/utils/itti_analyzer/libparser/enum_type.c deleted file mode 100644 index dbc99095bc..0000000000 --- a/common/utils/itti_analyzer/libparser/enum_type.c +++ /dev/null @@ -1,124 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "enum_type.h" -#include "ui_interface.h" - -char *enum_type_get_name_from_value(types_t *type, uint32_t value) -{ - char *enum_name = "UNKNOWN"; - types_t *enum_value; - - /* Loop on each enumeration values */ - for (enum_value = type->child; enum_value; enum_value = enum_value->next) { - if (value == enum_value->init_value) { - enum_name = enum_value->name; - break; - } - } - return enum_name; -} - -int enum_type_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - uint32_t value = 0; - types_t *values; - - DISPLAY_PARSE_INFO("enum", type->name, offset, parent_offset); - - value = buffer_get_uint32_t(buffer, parent_offset + offset); - - for (values = type->child; values; values = values->next) { - if (value == values->init_value) { - values->parent = type; - values->type_dissect_from_buffer( - values, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset, - type->name == NULL ? indent: indent + DISPLAY_TAB_SIZE, FALSE); - break; - } - } - if (values == NULL) { - int length = 0; - char cbuf[50]; - - length = sprintf(cbuf, "(0x%08x) UNKNOWN;\n", value); - ui_set_signal_text_cb(user_data, cbuf, length); - } - - return 0; -} - -int enum_type_file_print(types_t *type, int indent, FILE *file) -{ - types_t *values; - - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - INDENTED(file, indent+4, fprintf(file, "Artificial .: %d\n", type->artificial)); - INDENTED(file, indent+4, fprintf(file, "File .......: %s\n", type->file)); - INDENTED(file, indent+4, fprintf(file, "Line .......: %d\n", type->line)); - if (type->file_ref != NULL) - type->file_ref->type_file_print(type->file_ref, indent+4, file); - /* Call enum values display */ - for (values = type->child; values; values = values->next) { - values->type_file_print(values, indent + 4, file); - } - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int enum_type_hr_display(types_t *type, int indent) -{ - types_t *values; - - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - INDENTED(stdout, indent+4, printf("Artificial .: %d\n", type->artificial)); - INDENTED(stdout, indent+4, printf("File .......: %s\n", type->file)); - INDENTED(stdout, indent+4, printf("Line .......: %d\n", type->line)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display(type->file_ref, indent+4); - /* Call enum values display */ - for (values = type->child; values; values = values->next) { - values->type_hr_display(values, indent + 4); - } - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/enum_value_type.c b/common/utils/itti_analyzer/libparser/enum_value_type.c deleted file mode 100644 index 801317daaf..0000000000 --- a/common/utils/itti_analyzer/libparser/enum_value_type.c +++ /dev/null @@ -1,99 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "enum_value_type.h" -#include "ui_interface.h" - -uint32_t last_enum_value; - -int enum_value_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - types_t *type_parent = NULL; - uint32_t value = 0; - - DISPLAY_PARSE_INFO("enum_value", type->name, offset, parent_offset); - - value = buffer_get_uint32_t(buffer, parent_offset + offset); - if (type->name) { - int length = 0; - char cbuf[50 + strlen(type->name)]; - - /* Search for enum variable name and check if it is used in association with a union type */ - { - if (type->parent != NULL) { - /* Ignore ENUMERATION and TYPEDEF parents */ - for (type_parent = type->parent; (type_parent != NULL) && ((type_parent->type == TYPE_ENUMERATION) || (type_parent->type == TYPE_TYPEDEF)); - type_parent = type_parent->parent) { - } - } - if ((type_parent != NULL) && (type_parent->name != NULL) && (strcmp(type_parent->name, "present") == 0)) - { - /* ASN1 union, keep the "present" member */ - last_enum_value = value; - } - else - { - last_enum_value = 0; - } - } - length = sprintf(cbuf, "(0x%08x) %s;\n", value, type->name); - ui_set_signal_text_cb(user_data, cbuf, length); - } - - return 0; -} - -int enum_value_file_print(types_t *type, int indent, FILE *file) -{ - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Value ......: %d\n", type->init_value)); - if (type->file_ref != NULL) - type->file_ref->type_file_print(type->file_ref, indent+4, file); - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int enum_value_type_hr_display(types_t *type, int indent) -{ - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Value ......: %d\n", type->init_value)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display(type->file_ref, indent+4); - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/field_type.c b/common/utils/itti_analyzer/libparser/field_type.c deleted file mode 100644 index b64d3bd0c1..0000000000 --- a/common/utils/itti_analyzer/libparser/field_type.c +++ /dev/null @@ -1,180 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "rc.h" - -#include "field_type.h" -#include "buffers.h" -#include "ui_interface.h" - -int field_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - int length = 0; - char cbuf[50 + (type->name ? strlen (type->name) : 0)]; - types_t *type_child; - char array_info[50]; - new_line = FALSE; - - DISPLAY_PARSE_INFO("field", type->name, offset, parent_offset); - - CHECK_FCT(buffer_has_enouch_data(buffer, parent_offset + offset, type->size / 8)); - - if (type->bits == -1) { - if ((type->name != NULL) && (strcmp(type->name, "_asn_ctx") == 0)) { - /* Hide ASN1 asn_struct_ctx_t struct that hold context for parsing across buffer boundaries */ - /* - INDENTED_STRING(cbuf, indent, sprintf(cbuf, ".asn_ctx ...\n")); - length = strlen (cbuf); - - ui_set_signal_text_cb(user_data, cbuf, length); - */ - } - else { - if (type->child != NULL) { - /* Ignore TYPEDEF children */ - for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; type_child = - type_child->child) { - } - - if (type_child->type == TYPE_ARRAY) { - types_t *type_array_child; - - /* Ignore TYPEDEF children */ - for (type_array_child = type_child->child; - type_array_child != NULL && type_array_child->type == TYPE_TYPEDEF; type_array_child = - type_array_child->child) { - } - - sprintf (array_info, "[%d]", type_child->size / type_array_child->size); - } - else { - array_info[0] = '\0'; - } - - DISPLAY_TYPE("Fld"); - - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, ".%s%s = ", type->name ? type->name : "Field", array_info)); - ui_set_signal_text_cb(user_data, cbuf, length); - - if (type_child->type == TYPE_ARRAY) { - DISPLAY_BRACE(ui_set_signal_text_cb(user_data, "{", 1);) - ui_set_signal_text_cb(user_data, "\n", 1); - new_line = TRUE; - } - /* - if (type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) { - DISPLAY_BRACE(ui_set_signal_text_cb(user_data, "{", 1);) - ui_set_signal_text_cb(user_data, "\n", 1); - new_line = TRUE; - } - */ - - type->child->parent = type; - type->child->type_dissect_from_buffer( - type->child, ui_set_signal_text_cb, user_data, buffer, - parent_offset, offset + type->offset, new_line ? indent + DISPLAY_TAB_SIZE : indent, new_line); - - DISPLAY_BRACE( - if (type_child->type == TYPE_ARRAY) { - DISPLAY_TYPE("Fld"); - - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "};\n")); - ui_set_signal_text_cb(user_data, cbuf, length); - }); - /* - DISPLAY_BRACE( - if (type_child->type == TYPE_STRUCT || type_child->type == TYPE_UNION) { - DISPLAY_TYPE("Fld"); - INDENTED_STRING(cbuf, indent, sprintf(cbuf, "};\n")); - length = strlen (cbuf); - - ui_set_signal_text_cb(user_data, cbuf, length); - }); - */ - } - } - } - else { - /* The field is only composed of bits */ - uint32_t value = 0; - - CHECK_FCT(buffer_fetch_bits(buffer, offset + type->offset + parent_offset, type->bits, &value)); - - DISPLAY_TYPE("Fld"); - - INDENTED_STRING(cbuf, indent, - length = sprintf(cbuf, ".%s:%d = (0x%0*x) %d;\n", type->name ? type->name : "Field", type->bits, (type->bits + 3) / 4, value, value)); - ui_set_signal_text_cb(user_data, cbuf, length); - } - - return 0; -} - -int field_type_file_print(types_t *type, int indent, FILE *file) { - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Bits .......: %d\n", type->bits)); - INDENTED(file, indent+4, fprintf(file, "Type .......: %d\n", type->type_xml)); - INDENTED(file, indent+4, fprintf(file, "Offset .....: %d\n", type->offset)); - INDENTED(file, indent+4, fprintf(file, "Context ....: %d\n", type->context)); - INDENTED(file, indent+4, fprintf(file, "File .......: %s\n", type->file)); - INDENTED(file, indent+4, fprintf(file, "Line .......: %d\n", type->line)); - if (type->file_ref != NULL) - type->file_ref->type_file_print (type->file_ref, indent + 4, file); - if (type->child != NULL) - type->child->type_file_print (type->child, indent + 4, file); - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int field_type_hr_display(types_t *type, int indent) { - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Bits .......: %d\n", type->bits)); - INDENTED(stdout, indent+4, printf("Type .......: %d\n", type->type_xml)); - INDENTED(stdout, indent+4, printf("Offset .....: %d\n", type->offset)); - INDENTED(stdout, indent+4, printf("Context ....: %d\n", type->context)); - INDENTED(stdout, indent+4, printf("File .......: %s\n", type->file)); - INDENTED(stdout, indent+4, printf("Line .......: %d\n", type->line)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display (type->file_ref, indent + 4); - if (type->child != NULL) - type->child->type_hr_display (type->child, indent + 4); - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/fundamental_type.c b/common/utils/itti_analyzer/libparser/fundamental_type.c deleted file mode 100644 index 92dd1c75cb..0000000000 --- a/common/utils/itti_analyzer/libparser/fundamental_type.c +++ /dev/null @@ -1,144 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "fundamental_type.h" -#include "ui_interface.h" - -uint64_t fundamental_read_from_buffer(types_t *type, buffer_t *buffer, uint32_t offset, uint32_t parent_offset) { - uint64_t value; - - switch (type->size) { - case 8: - value = buffer_get_uint8_t (buffer, offset + parent_offset); - break; - - case 16: - value = buffer_get_uint16_t (buffer, offset + parent_offset); - break; - - case 32: - value = buffer_get_uint32_t (buffer, offset + parent_offset); - break; - - case 64: - value = buffer_get_uint64_t (buffer, offset + parent_offset); - break; - - default: - /* ??? */ - value = 0; - break; - } - return value; -} - -int fundamental_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - int length = 0; - char cbuf[200]; - int type_unsigned; - uint8_t value8; - uint16_t value16; - uint32_t value32; - uint64_t value64; - - DISPLAY_PARSE_INFO("fundamental", type->name, offset, parent_offset); - - memset (cbuf, 0, 200); - - type_unsigned = strstr (type->name, "unsigned") == NULL ? 0 : 1; - - value64 = fundamental_read_from_buffer(type, buffer, offset, parent_offset); - - indent = new_line ? indent : 0; - if (indent > 0) - { - DISPLAY_TYPE("Fun"); - } - switch (type->size) { - case 8: - value8 = (uint8_t) value64; - INDENTED_STRING(cbuf, indent, - length = sprintf(cbuf, type_unsigned ? "(0x%02" PRIx8 ") %3" PRIu8 ";\n" : "(0x%02" PRIx8 ") %4" PRId8 ";\n", value8, value8)); - break; - - case 16: - value16 = (uint16_t) value64; - INDENTED_STRING(cbuf, indent, - length = sprintf(cbuf, type_unsigned ? "(0x%04" PRIx16 ") %5" PRIu16 ";\n" : "(0x%04" PRIx16 ") %6" PRId16 ";\n", value16, value16)); - break; - - case 32: - value32 = (uint32_t) value64; - INDENTED_STRING(cbuf, indent, - length = sprintf(cbuf, type_unsigned ? "(0x%08" PRIx32 ") %9" PRIu32 ";\n" : "(0x%08" PRIx32 ") %10" PRId32 ";\n", value32, value32)); - break; - - case 64: - INDENTED_STRING(cbuf, indent, - length = sprintf(cbuf, type_unsigned ? "(0x%016" PRIx64 ") %20" PRIu64 ";\n" : "(0x%016" PRIx64 ") %20" PRId64 ";\n", value64, value64)); - break; - - default: - /* ??? */ - break; - } - ui_set_signal_text_cb(user_data, cbuf, length); - - return 0; -} - -int fundamental_type_file_print(types_t *type, int indent, FILE *file) { - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - if (type->file_ref != NULL) - type->file_ref->type_file_print (type->file_ref, indent + 4, file); - INDENTED(file, indent, fprintf(file, "\n")); - return 0; -} - -int fundamental_type_hr_display(types_t *type, int indent) { - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display (type->file_ref, indent + 4); - INDENTED(stdout, indent, printf("\n")); - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/fundamental_type.h b/common/utils/itti_analyzer/libparser/fundamental_type.h deleted file mode 100644 index 07ceb3b9ed..0000000000 --- a/common/utils/itti_analyzer/libparser/fundamental_type.h +++ /dev/null @@ -1,37 +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 - */ - -#include "types.h" - -#ifndef FUNDAMENTAL_TYPE_H_ -#define FUNDAMENTAL_TYPE_H_ - -uint64_t fundamental_read_from_buffer(types_t *type, buffer_t *buffer, uint32_t offset, uint32_t parent_offset); - -int fundamental_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int fundamental_type_file_print(types_t *type, int indent, FILE *file); - -int fundamental_type_hr_display(types_t *type, int indent); - -#endif /* FUNDAMENTAL_TYPE_H_ */ diff --git a/common/utils/itti_analyzer/libparser/intertask_contexts.h b/common/utils/itti_analyzer/libparser/intertask_contexts.h deleted file mode 100644 index cfe8f59402..0000000000 --- a/common/utils/itti_analyzer/libparser/intertask_contexts.h +++ /dev/null @@ -1,35 +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 - */ - -#include "fundamental_type.h" -#include "struct_type.h" - -#ifndef INTERTASK_CONTEXTS_H_ -#define INTERTASK_CONTEXTS_H_ - -typedef struct { - /* List of fundamental types that can contruct any other type */ - fundamental_type_t *ft_list; - - struct_type_t *struct_list; -} intertask_context_t; - -#endif /* INTERTASK_CONTEXTS_H_ */ diff --git a/common/utils/itti_analyzer/libparser/pointer_type.c b/common/utils/itti_analyzer/libparser/pointer_type.c deleted file mode 100644 index e4571f9f48..0000000000 --- a/common/utils/itti_analyzer/libparser/pointer_type.c +++ /dev/null @@ -1,103 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "pointer_type.h" -#include "ui_interface.h" - -int pointer_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - int length = 0, i; - char cbuf[200]; - - DISPLAY_PARSE_INFO("pointer", type->name, offset, parent_offset); - - memset (cbuf, 0, 200); - - uint8_t value[type->size / 8]; - - buffer_fetch_nbytes(buffer, parent_offset + offset, type->size / 8, value); - - indent = new_line ? indent : 0; - if (indent > 0) - { - DISPLAY_TYPE("Ptr"); - } - if (type->child && type->child->name) { - /* - INDENTED(stdout, indent, fprintf(stdout, "<%s>0x%08x\n", - type->child->name, value, type->child->name)); - */ - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "(%s *) 0x", type->child->name)); - } - else { - /* - INDENTED(stdout, indent, fprintf(stdout, "0x%08x\n", - value)); - */ - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "(void *) 0x")); - } - - /* Append the value */ - for (i = type->size / 8 - 1; i >= 0; i--) { - length += sprintf(&cbuf[length], "%02x", value[i]); - } - length += sprintf(&cbuf[length], ";\n"); - ui_set_signal_text_cb(user_data, cbuf, length); - - return 0; -} - -int pointer_type_file_print(types_t *type, int indent, FILE *file) { - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Type .......: %d\n", type->type_xml)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - if (type->child != NULL) { - if (type->child->type == TYPE_FUNCTION) { - INDENTED(file, indent+4, fprintf(file, "\n")); - INDENTED(file, indent+8, fprintf(file, "To be done\n")); - INDENTED(file, indent+4, fprintf(file, "\n")); - } else { - type->child->type_file_print (type->child, indent + 4, file); - } - } - if (type->file_ref != NULL) - type->file_ref->type_file_print (type->file_ref, indent + 4, file); - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int pointer_type_hr_display(types_t *type, int indent) { - return pointer_type_file_print(type, indent, stdout); -} diff --git a/common/utils/itti_analyzer/libparser/pointer_type.h b/common/utils/itti_analyzer/libparser/pointer_type.h deleted file mode 100644 index be2b6cc33c..0000000000 --- a/common/utils/itti_analyzer/libparser/pointer_type.h +++ /dev/null @@ -1,35 +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 - */ - -#include "types.h" - -#ifndef POINTER_TYPE_H_ -#define POINTER_TYPE_H_ - -int pointer_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int pointer_type_file_print(types_t *type, int indent, FILE *file); - -int pointer_type_hr_display(types_t *type, int indent); - -#endif /* POINTER_TYPE_H_ */ diff --git a/common/utils/itti_analyzer/libparser/reference_type.c b/common/utils/itti_analyzer/libparser/reference_type.c deleted file mode 100644 index 8d0fec4e61..0000000000 --- a/common/utils/itti_analyzer/libparser/reference_type.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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "reference_type.h" -#include "ui_interface.h" - -int reference_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - DISPLAY_PARSE_INFO("reference", type->name, offset, parent_offset); - - if (type->name) { - INDENTED(stdout, indent, fprintf(stdout, "<%s>\n", type->name)); - } - if (type->child != NULL) - type->child->type_dissect_from_buffer(type->child, ui_set_signal_text_cb, - user_data, buffer, offset, parent_offset, - type->name == NULL ? indent: indent + DISPLAY_TAB_SIZE, TRUE); - if (type->name) { - INDENTED(stdout, indent, fprintf(stdout, "\n", type->name)); - } - - return 0; -} - -int reference_type_file_print(types_t *type, int indent, FILE *file) -{ - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Type .......: %d\n", type->type_xml)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - INDENTED(file, indent+4, fprintf(file, "Context ....: %d\n", type->context)); - INDENTED(file, indent+4, fprintf(file, "Offset .....: %d\n", type->offset)); - INDENTED(file, indent+4, fprintf(file, "Line .......: %d\n", type->line)); - INDENTED(file, indent+4, fprintf(file, "File .......: %s\n", type->file)); - if (type->child != NULL) - type->child->type_file_print(type->child, indent+4, file); - if (type->file_ref != NULL) - type->file_ref->type_file_print(type->file_ref, indent+4, file); - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int reference_type_hr_display(types_t *type, int indent) -{ - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Type .......: %d\n", type->type_xml)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - INDENTED(stdout, indent+4, printf("Context ....: %d\n", type->context)); - INDENTED(stdout, indent+4, printf("Offset .....: %d\n", type->offset)); - INDENTED(stdout, indent+4, printf("Line .......: %d\n", type->line)); - INDENTED(stdout, indent+4, printf("File .......: %s\n", type->file)); - if (type->child != NULL) - type->child->type_hr_display(type->child, indent+4); - if (type->file_ref != NULL) - type->file_ref->type_hr_display(type->file_ref, indent+4); - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/reference_type.h b/common/utils/itti_analyzer/libparser/reference_type.h deleted file mode 100644 index da56e9f942..0000000000 --- a/common/utils/itti_analyzer/libparser/reference_type.h +++ /dev/null @@ -1,35 +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 - */ - -#include "types.h" - -#ifndef REFERENCE_TYPE_H_ -#define REFERENCE_TYPE_H_ - -int reference_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int reference_type_file_print(types_t *type, int indent, FILE *file); - -int reference_type_hr_display(types_t *type, int indent); - -#endif /* REFERENCE_TYPE_H_ */ diff --git a/common/utils/itti_analyzer/libparser/struct_type.c b/common/utils/itti_analyzer/libparser/struct_type.c deleted file mode 100644 index 09d5280ea5..0000000000 --- a/common/utils/itti_analyzer/libparser/struct_type.c +++ /dev/null @@ -1,148 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "rc.h" - -#include "struct_type.h" -#include "buffers.h" -#include "ui_callbacks.h" -#include "ui_interface.h" - -int struct_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - int i; - char cbuf[50 + (type->name ? strlen (type->name) : 0)]; - int length = 0; - char *name; - - memset (cbuf, 0, sizeof(cbuf)); - - DISPLAY_PARSE_INFO("structure", type->name, offset, parent_offset); - - if (new_line) { - DISPLAY_TYPE("Str"); - } - - if (type->name) { - name = type->name; - } - else { - name = "_anonymous_"; - } - - if ((strcmp (name, "IttiMsgText_s") == 0) && - (type->members_child[0] != NULL) && (strcmp (type->members_child[0]->name, "size") == 0) && - (type->members_child[1] != NULL) && (strcmp (type->members_child[1]->name, "text") == 0)) { - uint8_t *buf; - - length = buffer_get_uint32_t (buffer, offset + parent_offset); - buf = malloc (length + 1); - buf[0] = '\n'; - buffer_fetch_nbytes(buffer, parent_offset + offset + 32, length, &buf[1]); - length = ui_callback_check_string ((char *) &buf[1], length, 0); - ui_set_signal_text_cb(user_data, (char *) buf, length + 1); - } - else - { - INDENTED_STRING(cbuf, new_line ? indent : 0, length = sprintf (cbuf, "%s :", name)); - DISPLAY_BRACE(length += sprintf(&cbuf[length], " {");); - length += sprintf(&cbuf[length], "\n"); - ui_set_signal_text_cb(user_data, cbuf, length); - - for (i = 0; i < type->nb_members; i++) { - if (type->members_child[i] != NULL) - type->members_child[i]->type_dissect_from_buffer ( - type->members_child[i], ui_set_signal_text_cb, user_data, - buffer, offset, parent_offset, indent + DISPLAY_TAB_SIZE, TRUE); - } - } - - DISPLAY_BRACE( - DISPLAY_TYPE("Str"); - - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "};\n")); - ui_set_signal_text_cb(user_data, cbuf, length);) - - return 0; -} - -int struct_type_file_print(types_t *type, int indent, FILE *file) { - int i; - if (type == NULL) - return -1; - if (file == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - INDENTED(file, indent+4, fprintf(file, "Artificial .: %d\n", type->artificial)); - INDENTED(file, indent+4, fprintf(file, "File .......: %s\n", type->file)); - INDENTED(file, indent+4, fprintf(file, "Line .......: %d\n", type->line)); - INDENTED(file, indent+4, fprintf(file, "Members ....: %s\n", type->members)); - INDENTED(file, indent+4, fprintf(file, "Mangled ....: %s\n", type->mangled)); - INDENTED(file, indent+4, fprintf(file, "Demangled ..: %s\n", type->demangled)); - if (type->file_ref != NULL) - type->file_ref->type_file_print (type->file_ref, indent + 4, file); - for (i = 0; i < type->nb_members; i++) { - if (type->members_child[i] != NULL) - type->members_child[i]->type_file_print (type->members_child[i], indent + 4, file); - } - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int struct_type_hr_display(types_t *type, int indent) { - int i; - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - INDENTED(stdout, indent+4, printf("Artificial .: %d\n", type->artificial)); - INDENTED(stdout, indent+4, printf("File .......: %s\n", type->file)); - INDENTED(stdout, indent+4, printf("Line .......: %d\n", type->line)); - INDENTED(stdout, indent+4, printf("Members ....: %s\n", type->members)); - INDENTED(stdout, indent+4, printf("Mangled ....: %s\n", type->mangled)); - INDENTED(stdout, indent+4, printf("Demangled ..: %s\n", type->demangled)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display (type->file_ref, indent + 4); - for (i = 0; i < type->nb_members; i++) { - if (type->members_child[i] != NULL) - type->members_child[i]->type_hr_display (type->members_child[i], indent + 4); - } - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/struct_type.h b/common/utils/itti_analyzer/libparser/struct_type.h deleted file mode 100644 index 29d4113b6f..0000000000 --- a/common/utils/itti_analyzer/libparser/struct_type.h +++ /dev/null @@ -1,35 +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 - */ - -#include "types.h" - -#ifndef STRUCT_TYPE_H_ -#define STRUCT_TYPE_H_ - -int struct_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int struct_type_hr_display(types_t *type, int indent); - -int struct_type_file_print(types_t *type, int indent, FILE *file); - -#endif /* STRUCT_TYPE_H_ */ diff --git a/common/utils/itti_analyzer/libparser/typedef_type.c b/common/utils/itti_analyzer/libparser/typedef_type.c deleted file mode 100644 index e5cee1a1cf..0000000000 --- a/common/utils/itti_analyzer/libparser/typedef_type.c +++ /dev/null @@ -1,113 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "typedef_type.h" -#include "ui_interface.h" - -int typedef_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - int length = 0; - char cbuf[50 + (type->name ? strlen (type->name) : 0)]; - types_t *type_child = NULL; - - DISPLAY_PARSE_INFO("typedef", type->name, offset, parent_offset); - - if (type->child != NULL) { - /* Ignore TYPEDEF children */ - for (type_child = type->child; type_child != NULL && type_child->type == TYPE_TYPEDEF; type_child = - type_child->child) { - } - } - - if ((type_child == NULL) || (type_child->type != TYPE_FUNDAMENTAL)) - { - INDENTED_STRING(cbuf, new_line ? indent : 0, length = sprintf (cbuf, "%s, ", type->name)); - ui_set_signal_text_cb(user_data, cbuf, length); - - new_line = FALSE; - } - - /* Simply call next_type */ - if (type->child != NULL) { - type->child->parent = type; - type->child->type_dissect_from_buffer( - type->child, ui_set_signal_text_cb, user_data, buffer, offset, parent_offset, indent, new_line); - } - - return 0; -} - -int typedef_type_file_print(types_t *type, int indent, FILE *file) -{ - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Type .......: %d\n", type->type_xml)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - INDENTED(file, indent+4, fprintf(file, "Artificial .: %d\n", type->artificial)); - INDENTED(file, indent+4, fprintf(file, "File .......: %s\n", type->file)); - INDENTED(file, indent+4, fprintf(file, "Line .......: %d\n", type->line)); - INDENTED(file, indent+4, fprintf(file, "Members ....: %s\n", type->members)); - INDENTED(file, indent+4, fprintf(file, "Mangled ....: %s\n", type->mangled)); - INDENTED(file, indent+4, fprintf(file, "Demangled ..: %s\n", type->demangled)); - if (type->file_ref != NULL) - type->file_ref->type_file_print(type->file_ref, indent+4, file); - if (type->child != NULL) - type->child->type_file_print(type->child, indent+4, file); - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int typedef_type_hr_display(types_t *type, int indent) -{ - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Type .......: %d\n", type->type_xml)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - INDENTED(stdout, indent+4, printf("Artificial .: %d\n", type->artificial)); - INDENTED(stdout, indent+4, printf("File .......: %s\n", type->file)); - INDENTED(stdout, indent+4, printf("Line .......: %d\n", type->line)); - INDENTED(stdout, indent+4, printf("Members ....: %s\n", type->members)); - INDENTED(stdout, indent+4, printf("Mangled ....: %s\n", type->mangled)); - INDENTED(stdout, indent+4, printf("Demangled ..: %s\n", type->demangled)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display(type->file_ref, indent+4); - if (type->child != NULL) - type->child->type_hr_display(type->child, indent+4); - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/typedef_type.h b/common/utils/itti_analyzer/libparser/typedef_type.h deleted file mode 100644 index b5710dbfcb..0000000000 --- a/common/utils/itti_analyzer/libparser/typedef_type.h +++ /dev/null @@ -1,35 +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 - */ - -#include "types.h" - -#ifndef TYPEDEF_TYPE_H_ -#define TYPEDEF_TYPE_H_ - -int typedef_type_file_print(types_t *type, int indent, FILE *file); - -int typedef_type_hr_display(types_t *type, int indent); - -int typedef_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -#endif /* TYPEDEF_TYPE_H_ */ diff --git a/common/utils/itti_analyzer/libparser/types.c b/common/utils/itti_analyzer/libparser/types.c deleted file mode 100644 index 406db5249c..0000000000 --- a/common/utils/itti_analyzer/libparser/types.c +++ /dev/null @@ -1,147 +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 - */ - -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "types.h" -#include "array_type.h" -#include "enum_type.h" -#include "fundamental_type.h" -#include "struct_type.h" -#include "union_type.h" -#include "typedef_type.h" -#include "enum_value_type.h" -#include "file_type.h" -#include "field_type.h" -#include "reference_type.h" -#include "pointer_type.h" - -types_t *type_new(enum type_e type) -{ - types_t *new_p; - - new_p = calloc(1, sizeof(types_t)); - - new_p->type = type; - - switch(type) { - case TYPE_FUNCTION: - /* Nothing to do for now. Display is done by pointer type */ - break; - case TYPE_ENUMERATION: - new_p->type_hr_display = enum_type_hr_display; - new_p->type_file_print = enum_type_file_print; - new_p->type_dissect_from_buffer = enum_type_dissect_from_buffer; - break; - case TYPE_FUNDAMENTAL: - new_p->type_hr_display = fundamental_type_hr_display; - new_p->type_file_print = fundamental_type_file_print; - new_p->type_dissect_from_buffer = fundamental_dissect_from_buffer; - break; - case TYPE_STRUCT: - new_p->type_hr_display = struct_type_hr_display; - new_p->type_file_print = struct_type_file_print; - new_p->type_dissect_from_buffer = struct_dissect_from_buffer; - break; - case TYPE_UNION: - new_p->type_hr_display = union_type_hr_display; - new_p->type_file_print = union_type_file_print; - new_p->type_dissect_from_buffer = union_dissect_from_buffer; - break; - case TYPE_TYPEDEF: - new_p->type_hr_display = typedef_type_hr_display; - new_p->type_file_print = typedef_type_file_print; - new_p->type_dissect_from_buffer = typedef_dissect_from_buffer; - break; - case TYPE_ENUMERATION_VALUE: - new_p->type_hr_display = enum_value_type_hr_display; - new_p->type_file_print = enum_value_file_print; - new_p->type_dissect_from_buffer = enum_value_dissect_from_buffer; - break; - case TYPE_FILE: - new_p->type_hr_display = file_type_hr_display; - new_p->type_file_print = file_type_file_print; -// new_p->type_dissect_from_buffer = file_dissect_from_buffer; - break; - case TYPE_FIELD: - new_p->type_hr_display = field_type_hr_display; - new_p->type_file_print = field_type_file_print; - new_p->type_dissect_from_buffer = field_dissect_from_buffer; - break; - case TYPE_REFERENCE: - new_p->type_hr_display = reference_type_hr_display; - new_p->type_file_print = reference_type_file_print; - new_p->type_dissect_from_buffer = reference_dissect_from_buffer; - break; - case TYPE_ARRAY: - new_p->type_hr_display = array_type_hr_display; - new_p->type_file_print = array_type_file_print; - new_p->type_dissect_from_buffer = array_dissect_from_buffer; - break; - case TYPE_POINTER: - new_p->type_hr_display = pointer_type_hr_display; - new_p->type_file_print = pointer_type_file_print; - new_p->type_dissect_from_buffer = pointer_dissect_from_buffer; - break; - default: - break; - } - - return new_p; -} - -int types_insert_tail(types_t **head, types_t *to_insert) -{ - if (to_insert == NULL || head == NULL) - return -1; - if (*head == NULL) { - *head = to_insert; - } else { - types_t *last = *head; - while(last->next != NULL) { - last = last->next; - } - last->next = to_insert; - to_insert->previous = last; - } - to_insert->head = *head; - return 0; -} - -void types_hr_display(types_t *head) -{ - types_t *current = head; - - if (head == NULL) { - printf("Empty list\n"); - /* Empty list */ - return; - } - - while((current = current->next) != NULL) - { - current->type_hr_display(current, 0); - } -} diff --git a/common/utils/itti_analyzer/libparser/types.h b/common/utils/itti_analyzer/libparser/types.h deleted file mode 100644 index c449c445fd..0000000000 --- a/common/utils/itti_analyzer/libparser/types.h +++ /dev/null @@ -1,187 +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 - */ - -#include - -#include "buffers.h" -#include "ui_main_screen.h" -#include "ui_interface.h" - -#ifndef TYPES_H_ -#define TYPES_H_ - -/* Activate to display the type at the beginning of the line (debug option) */ -#define ENABLE_DISPLAY_TYPE 0 - -/* Activate to display the parse information before processing each item (debug option) */ -#define ENABLE_DISPLAY_PARSE_INFO 0 - -/* Activate to show braces, in increase the number of displayed lines (formating option)*/ -#define ENABLE_DISPLAY_BRACE 1 - -#if (ENABLE_DISPLAY_TYPE != 0) -# define DISPLAY_TYPE(tYPE) ui_set_signal_text_cb(user_data, tYPE" ", strlen(tYPE) + 1); -#else -# define DISPLAY_TYPE(tYPE) -#endif - -#define DISPLAY_TAB_SIZE (2) - -#if (ENABLE_DISPLAY_PARSE_INFO != 0) -# define DISPLAY_PARSE_INFO(tYPE, nAME, oFFSET, pARENToFFSET) \ - { \ - char buf[200]; \ - sprintf(buf, "/* %s \"%s\" %d %d */\n", tYPE, nAME, oFFSET, pARENToFFSET); \ - ui_set_signal_text_cb(user_data, buf, strlen(buf)); \ - } -#else -# define DISPLAY_PARSE_INFO(tYPE, nAME, oFFSET, pARENToFFSET) -#endif - -#if (ENABLE_DISPLAY_BRACE != 0) -# define DISPLAY_BRACE(cODE) if (ui_main_data.display_brace) {cODE} -#else -# define DISPLAY_BRACE(cODE) -#endif - -enum type_e { - TYPE_ENUMERATION, - TYPE_ENUMERATION_VALUE, - TYPE_STRUCT, - TYPE_UNION, - TYPE_FUNDAMENTAL, - TYPE_TYPEDEF, - TYPE_ARRAY, - TYPE_REFERENCE, - TYPE_FIELD, - TYPE_FUNCTION, - TYPE_ARGUMENT, - TYPE_POINTER, - TYPE_FILE, -}; - -/* Forward declarations */ -struct types_s; - -typedef int (*type_hr_display_t)(struct types_s *type, int indent); -typedef int (*type_ui_display_t)(struct types_s *type, int indent); -typedef int (*type_file_print_t)(struct types_s *type, int indent, FILE *file); - -/** - * type_dissect_from_buffer_t - * @param type The current type - * @param ui_set_signal_text_cb GUI display function - * @param user_data Transparent data to pass to the GUI display function - * @param buffer The buffer containing data to dissect - * @param offset offset of field from the beginning of the parent - * @param parent_offset offset of the parent from begining - **/ -typedef int (*type_dissect_from_buffer_t)( - struct types_s *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -typedef struct types_s { - /* The type of the current description */ - enum type_e type; - - /* Printable name for the current type */ - char *name; - - int type_xml; - - int size; - int align; - int bits; - - /* Used only for arrays */ - int min; - int max; - - int context; - - /* Init value for enumerations */ - int init_value; - - int incomplete; - - /* Id of the type as defined in XML file */ - int id; - int artificial; - - char *mangled; - char *demangled; - - /* List of members in constructed types */ - char *members; - - /* The file containing the definition */ - char *file; - /* Line number of the current definition */ - int line; - - /* offset of the field in the parent type - * -1 means no parent - */ - int offset; - - struct types_s *previous; - struct types_s *next; - struct types_s *parent; - struct types_s *child; - struct types_s *file_ref; - /* Reference to the head */ - struct types_s *head; - - /* For structures or union */ - int nb_members; - struct types_s **members_child; - - /* Some procedures to display the type on terminal */ - type_hr_display_t type_hr_display; - /* Some procedures to display the type on UI */ - type_ui_display_t type_ui_display; - /* Procedure to display the type to a file */ - type_file_print_t type_file_print; - /* Dissect the type */ - type_dissect_from_buffer_t type_dissect_from_buffer; -} types_t; - -types_t *type_new(enum type_e type); - -int types_insert_tail(types_t **head, types_t *to_insert); - -void types_hr_display(types_t *head); - -#define INDENTED(fILE, x, y) \ -do { \ - int indentation = x; \ - while(indentation--) fprintf(fILE, " "); \ - y; \ -} while(0) - -#define INDENTED_STRING(sTR, x, y) \ -do { \ - int indentation = x; \ - while(indentation--) ui_set_signal_text_cb(user_data, " ", 1); \ - y; \ -} while(0) - -#endif /* TYPES_H_ */ diff --git a/common/utils/itti_analyzer/libparser/union_type.c b/common/utils/itti_analyzer/libparser/union_type.c deleted file mode 100644 index f38b7a1ccc..0000000000 --- a/common/utils/itti_analyzer/libparser/union_type.c +++ /dev/null @@ -1,188 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include "rc.h" - -#include "enum_value_type.h" -#include "union_type.h" -#include "../libresolver/locate_root.h" -#include "ui_interface.h" - -/* There is only one special case of union which is associated to an index: the message id */ -int union_msg_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - uint32_t message_id; - int length = 0; - char cbuf[200]; - - DISPLAY_PARSE_INFO("union_msg", type->name, offset, parent_offset); - - CHECK_FCT(get_message_id(type->head, buffer, &message_id)); - - if (type->name) { - DISPLAY_TYPE("Uni"); - - length = sprintf(cbuf, "%s |", type->name); - DISPLAY_BRACE(length += sprintf(&cbuf[length], " {");); - length += sprintf(&cbuf[length], "\n"); - ui_set_signal_text_cb(user_data, cbuf, length); - } - - if (type->members_child[message_id] != NULL) - type->members_child[message_id]->type_dissect_from_buffer( - type->members_child[message_id], ui_set_signal_text_cb, user_data, - buffer, offset, parent_offset, type->name == NULL ? indent : indent + DISPLAY_TAB_SIZE, TRUE); - - DISPLAY_BRACE( - if (type->name) { - DISPLAY_TYPE("Uni"); - - INDENTED_STRING(cbuf, indent, length = sprintf(cbuf, "};\n")); - ui_set_signal_text_cb(user_data, cbuf, length); - }); - - return RC_OK; -} - -int union_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line) -{ - int length = 0; - char cbuf[50 + (type->name ? strlen (type->name) : 0)]; - char *name; - int union_child = 0; - - DISPLAY_PARSE_INFO("union", type->name, offset, parent_offset); - - memset (cbuf, 0, sizeof(cbuf)); - -// CHECK_FCT(buffer_has_enouch_data(buffer, offset + parent_offset, type->size / 8)); - - if (type->name) { - name = type->name; - } - else { - name = "_anonymous_"; - } - if (new_line) { - DISPLAY_TYPE("Uni"); - } - INDENTED_STRING(cbuf, new_line ? indent : 0, length = sprintf(cbuf, "%s |", name)); - DISPLAY_BRACE(length += sprintf(&cbuf[length], " {");); - length += sprintf(&cbuf[length], "\n"); - ui_set_signal_text_cb(user_data, cbuf, length); - - if (type->name) { - if (type->parent != NULL) - { - if ((type->parent->name != NULL) && (strcmp(type->parent->name, "choice") == 0)) - { - /* ASN1 union */ - - if ((last_enum_value > 0) && (last_enum_value <= type->nb_members)) - { - union_child = last_enum_value - 1; - - g_debug("ASN1 union \"%s\' detected, use member %d", type->name, union_child); - } - } - } - } - - - /* Only dissect the first field present in unions */ - if (type->members_child[union_child] != NULL) - type->members_child[union_child]->type_dissect_from_buffer( - type->members_child[union_child], ui_set_signal_text_cb, user_data, buffer, - offset, parent_offset, indent + DISPLAY_TAB_SIZE, TRUE); - - DISPLAY_BRACE( - DISPLAY_TYPE("Uni"); - INDENTED_STRING(cbuf, indent, sprintf(cbuf, "};\n")); - - length = strlen (cbuf); - - ui_set_signal_text_cb(user_data, cbuf, length);); - - return 0; -} - -int union_type_file_print(types_t *type, int indent, FILE *file) { - int i; - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Size .......: %d\n", type->size)); - INDENTED(file, indent+4, fprintf(file, "Align ......: %d\n", type->align)); - INDENTED(file, indent+4, fprintf(file, "Artificial .: %d\n", type->artificial)); - INDENTED(file, indent+4, fprintf(file, "File .......: %s\n", type->file)); - INDENTED(file, indent+4, fprintf(file, "Line .......: %d\n", type->line)); - INDENTED(file, indent+4, fprintf(file, "Members ....: %s\n", type->members)); - INDENTED(file, indent+4, fprintf(file, "Mangled ....: %s\n", type->mangled)); - INDENTED(file, indent+4, fprintf(file, "Demangled ..: %s\n", type->demangled)); - if (type->file_ref != NULL) - type->file_ref->type_file_print (type->file_ref, indent + 4, file); - for (i = 0; i < type->nb_members; i++) { - if (type->members_child[i] != NULL) - type->members_child[i]->type_file_print (type->members_child[i], indent + 4, file); - } - INDENTED(file, indent, fprintf(file, "\n")); - - return 0; -} - -int union_type_hr_display(types_t *type, int indent) { - int i; - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Size .......: %d\n", type->size)); - INDENTED(stdout, indent+4, printf("Align ......: %d\n", type->align)); - INDENTED(stdout, indent+4, printf("Artificial .: %d\n", type->artificial)); - INDENTED(stdout, indent+4, printf("File .......: %s\n", type->file)); - INDENTED(stdout, indent+4, printf("Line .......: %d\n", type->line)); - INDENTED(stdout, indent+4, printf("Members ....: %s\n", type->members)); - INDENTED(stdout, indent+4, printf("Mangled ....: %s\n", type->mangled)); - INDENTED(stdout, indent+4, printf("Demangled ..: %s\n", type->demangled)); - if (type->file_ref != NULL) - type->file_ref->type_hr_display (type->file_ref, indent + 4); - for (i = 0; i < type->nb_members; i++) { - if (type->members_child[i] != NULL) - type->members_child[i]->type_hr_display (type->members_child[i], indent + 4); - } - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/common/utils/itti_analyzer/libparser/xml_parse.c b/common/utils/itti_analyzer/libparser/xml_parse.c deleted file mode 100644 index 72447e7669..0000000000 --- a/common/utils/itti_analyzer/libparser/xml_parse.c +++ /dev/null @@ -1,904 +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 - */ - -#include -#include - -#define G_LOG_DOMAIN ("PARSER") - -#include - -#include -#include - -#include "logs.h" -#include "types.h" -#include "xml_parse.h" -#include "union_type.h" - -#include "ui_interface.h" -#include "ui_main_screen.h" -#include "ui_notif_dlg.h" -#include "ui_filters.h" - -#include "../libresolver/locate_root.h" -#include "../libresolver/resolvers.h" - -extern int debug_parser; - -#if (ENABLE_DISPLAY_PARSE_INFO != 0) -# define INDENT_START 30 -#else -# define INDENT_START 0 -#endif - -void *xml_raw_data; -uint32_t xml_raw_data_size; - -types_t *xml_head; -types_t *root; - -static int xml_parse_doc(xmlDocPtr doc); - -static int parse_attribute_name(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "name")) == NULL) { - if (mandatory) { - g_error("cannot retrieve name attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - return -1; - } - else { - g_debug("cannot retrieve name attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - return 0; - } - } - type->name = strdup ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_id(xmlNode *node, types_t *type) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "id")) == NULL) { - g_error("cannot retrieve id attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - return -1; - } - type->id = atoi ((char *) &node_attribute->children->content[1]); - return 0; -} - -static int parse_attribute_size(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "size")) == NULL) { - if (mandatory) { - g_error("cannot retrieve size attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->size = -1; - return -1; - } - else { - g_debug("cannot retrieve size attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->size = -1; - return 0; - } - } - type->size = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_align(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "align")) == NULL) { - if (mandatory) { - g_error("cannot retrieve align attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->align = -1; - return -1; - } - else { - g_debug("cannot retrieve align attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->align = -1; - return 0; - } - } - type->align = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_line(xmlNode *node, types_t *type) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "line")) == NULL) { - type->line = -1; - return 0; - } - type->line = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_file(xmlNode *node, types_t *type) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "file")) == NULL) { - type->file = NULL; - return 0; - } - type->file = strdup ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_context(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "context")) == NULL) { - if (mandatory) { - g_error("cannot retrieve context attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->context = -1; - return -1; - } - else { - type->context = -1; - return 0; - } - } - type->context = atoi ((char *) &node_attribute->children->content[1]); - return 0; -} - -static int parse_attribute_artificial(xmlNode *node, types_t *type) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "artificial")) == NULL) { - g_debug("cannot retrieve artificial attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->artificial = -1; - return 0; - } - type->artificial = atoi ((char *) &node_attribute->children->content[1]); - return 0; -} - -static int parse_attribute_init(xmlNode *node, types_t *type) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "init")) == NULL) { - g_error("cannot retrieve init attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->init_value = -1; - return 0; - } - type->init_value = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_members(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "members")) == NULL) { - if (mandatory) { - g_error("cannot retrieve members attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->members = 0; - return -1; - } - else { - g_debug("cannot retrieve members attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->members = 0; - return 0; - } - } - type->members = strdup ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_mangled(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "mangled")) == NULL) { - if (mandatory) { - g_error("cannot retrieve mangled attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->mangled = 0; - return -1; - } - else { - g_debug("cannot retrieve mangled attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->mangled = 0; - return 0; - } - } - type->mangled = strdup ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_demangled(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "mangled")) == NULL) { - if (mandatory) { - g_error("cannot retrieve demangled attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->demangled = 0; - return -1; - } - else { - g_debug("cannot retrieve demangled attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->demangled = 0; - return 0; - } - } - type->demangled = strdup ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_offset(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "offset")) == NULL) { - if (mandatory) { - g_error("cannot retrieve offset attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->offset = -1; - return -1; - } - else { - g_debug("cannot retrieve offset attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->offset = -1; - return 0; - } - } - type->offset = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_bits(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "bits")) == NULL) { - if (mandatory) { - g_error("cannot retrieve bits attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->bits = -1; - return -1; - } - else { - g_debug("cannot retrieve bits attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->bits = -1; - return 0; - } - } - type->bits = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_type(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "type")) == NULL) { - if (mandatory) { - g_error("cannot retrieve type attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->type_xml = 0; - return -1; - } - else { - g_debug("cannot retrieve type attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->type_xml = 0; - return 0; - } - } - type->type_xml = atoi ((char *) &node_attribute->children->content[1]); - return 0; -} - -static int parse_attribute_min(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "min")) == NULL) { - if (mandatory) { - g_error("cannot retrieve min attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->min = 0; - return -1; - } - else { - g_debug("cannot retrieve min attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->min = 0; - return 0; - } - } - type->min = atoi ((char *) node_attribute->children->content); - return 0; -} - -static int parse_attribute_max(xmlNode *node, types_t *type, int mandatory) { - xmlAttrPtr node_attribute; - if ((node_attribute = xmlHasProp (node, (xmlChar *) "max")) == NULL) { - if (mandatory) { - g_error("cannot retrieve max attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->max = 0; - return -1; - } - else { - g_debug("cannot retrieve max attribute in node %s, %s:%ld", - (char *)node->name, node->doc->URL, XML_GET_LINE(node)); - type->max = 0; - return 0; - } - } - type->max = atoi ((char *) &node_attribute->children->content[1]); - return 0; -} - -static int parse_enum_values(xmlNode *node, types_t *parent) { - types_t *new; - - if (node == NULL || parent == NULL) - return -1; - - new = type_new (TYPE_ENUMERATION_VALUE); - - CHECK_FCT(parse_attribute_name(node, new, 1)); - CHECK_FCT(parse_attribute_init(node, new)); - - CHECK_FCT(types_insert_tail(&parent->child, new)); - - return 0; -} - -static int parse_enumeration(xmlNode *node, types_t **head) { - types_t *new; - xmlNode *enum_value_node; - - if (node == NULL) - return -1; - - new = type_new (TYPE_ENUMERATION); - - CHECK_FCT(parse_attribute_name(node, new, 1)); - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_size(node, new, 1)); - CHECK_FCT(parse_attribute_align(node, new, 1)); - CHECK_FCT(parse_attribute_context(node, new, 0)); - CHECK_FCT(parse_attribute_line(node, new)); - CHECK_FCT(parse_attribute_file(node, new)); - CHECK_FCT(parse_attribute_artificial(node, new)); - - CHECK_FCT(types_insert_tail(head, new)); - - /* Parse enum values */ - for (enum_value_node = node->children; enum_value_node; enum_value_node = enum_value_node->next) { - if (strcmp ((char *) enum_value_node->name, "EnumValue") == 0) - CHECK_FCT(parse_enum_values(enum_value_node, new)); - } - - return 0; -} - -static int parse_union(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_UNION); - - CHECK_FCT(parse_attribute_name(node, new, 0)); - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_size(node, new, 1)); - CHECK_FCT(parse_attribute_align(node, new, 1)); - CHECK_FCT(parse_attribute_context(node, new, 0)); - CHECK_FCT(parse_attribute_members(node, new, 0)); - CHECK_FCT(parse_attribute_line(node, new)); - CHECK_FCT(parse_attribute_file(node, new)); - CHECK_FCT(parse_attribute_artificial(node, new)); - CHECK_FCT(parse_attribute_mangled(node, new, 0)); - CHECK_FCT(parse_attribute_demangled(node, new, 0)); - - if (new->name) - if (strcmp (new->name, "msg_s") == 0) - new->type_dissect_from_buffer = union_msg_dissect_from_buffer; - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_fundamental(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_FUNDAMENTAL); - - CHECK_FCT(parse_attribute_name(node, new, 1)); - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_size(node, new, 0)); - CHECK_FCT(parse_attribute_align(node, new, 0)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_struct(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_STRUCT); - - CHECK_FCT(parse_attribute_name(node, new, 0)); - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_size(node, new, 0)); - CHECK_FCT(parse_attribute_align(node, new, 0)); - CHECK_FCT(parse_attribute_file(node, new)); - CHECK_FCT(parse_attribute_line(node, new)); - CHECK_FCT(parse_attribute_context(node, new, 0)); - CHECK_FCT(parse_attribute_artificial(node, new)); - CHECK_FCT(parse_attribute_members(node, new, 0)); - CHECK_FCT(parse_attribute_mangled(node, new, 0)); - CHECK_FCT(parse_attribute_demangled(node, new, 0)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_typedef(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_TYPEDEF); - - CHECK_FCT(parse_attribute_name(node, new, 1)); - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_file(node, new)); - CHECK_FCT(parse_attribute_line(node, new)); - CHECK_FCT(parse_attribute_type(node, new, 1)); - CHECK_FCT(parse_attribute_size(node, new, 0)); - CHECK_FCT(parse_attribute_align(node, new, 0)); - CHECK_FCT(parse_attribute_context(node, new, 0)); - CHECK_FCT(parse_attribute_artificial(node, new)); - CHECK_FCT(parse_attribute_members(node, new, 0)); - CHECK_FCT(parse_attribute_mangled(node, new, 0)); - CHECK_FCT(parse_attribute_demangled(node, new, 0)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_field(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_FIELD); - - CHECK_FCT(parse_attribute_name(node, new, 1)); - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_type(node, new, 1)); - CHECK_FCT(parse_attribute_size(node, new, 0)); - CHECK_FCT(parse_attribute_bits(node, new, 0)); - CHECK_FCT(parse_attribute_offset(node, new, 0)); - CHECK_FCT(parse_attribute_align(node, new, 0)); - CHECK_FCT(parse_attribute_context(node, new, 0)); - CHECK_FCT(parse_attribute_artificial(node, new)); - CHECK_FCT(parse_attribute_members(node, new, 0)); - CHECK_FCT(parse_attribute_mangled(node, new, 0)); - CHECK_FCT(parse_attribute_demangled(node, new, 0)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_file(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_FILE); - - CHECK_FCT(parse_attribute_name(node, new, 1)); - CHECK_FCT(parse_attribute_id(node, new)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_reference_type(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_REFERENCE); - - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_type(node, new, 1)); - CHECK_FCT(parse_attribute_size(node, new, 1)); - CHECK_FCT(parse_attribute_align(node, new, 1)); - CHECK_FCT(parse_attribute_context(node, new, 0)); - CHECK_FCT(parse_attribute_offset(node, new, 0)); - CHECK_FCT(parse_attribute_file(node, new)); - CHECK_FCT(parse_attribute_line(node, new)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_array_type(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_ARRAY); - - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_type(node, new, 1)); - CHECK_FCT(parse_attribute_size(node, new, 0)); - CHECK_FCT(parse_attribute_align(node, new, 1)); - CHECK_FCT(parse_attribute_min(node, new, 1)); - CHECK_FCT(parse_attribute_max(node, new, 1)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_pointer_type(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_POINTER); - - CHECK_FCT(parse_attribute_id(node, new)); - CHECK_FCT(parse_attribute_type(node, new, 1)); - CHECK_FCT(parse_attribute_size(node, new, 1)); - CHECK_FCT(parse_attribute_align(node, new, 1)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -static int parse_function_type(xmlNode *node, types_t **head) { - types_t *new; - - if (node == NULL) - return -1; - - new = type_new (TYPE_FUNCTION); - - CHECK_FCT(parse_attribute_id(node, new)); - - CHECK_FCT(types_insert_tail(head, new)); - - return 0; -} - -/** - * print_element_names: - * @a_node: the initial xml node to consider. - * - * Prints the names of the all the xml elements - * that are siblings or children of a given xml node. - */ -static int parse_elements(xmlNode * a_node, types_t **head) { - xmlNode *cur_node = NULL; - xmlNode *child_node = NULL; - - for (cur_node = a_node; cur_node; cur_node = cur_node->next) { - for (child_node = cur_node->children; child_node; child_node = child_node->next) { - if (child_node->type == XML_ELEMENT_NODE) { - if (strcmp ((char *) child_node->name, "Enumeration") == 0) { - CHECK_FCT_DO(parse_enumeration(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "FundamentalType") == 0) { - CHECK_FCT_DO(parse_fundamental(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "Struct") == 0) { - CHECK_FCT_DO(parse_struct(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "Union") == 0) { - CHECK_FCT_DO(parse_union(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "Typedef") == 0) { - CHECK_FCT_DO(parse_typedef(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "File") == 0) { - CHECK_FCT_DO(parse_file(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "Field") == 0) { - CHECK_FCT_DO(parse_field(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "ReferenceType") == 0) { - CHECK_FCT_DO(parse_reference_type(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "ArrayType") == 0) { - CHECK_FCT_DO(parse_array_type(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "PointerType") == 0) { - CHECK_FCT_DO(parse_pointer_type(child_node, head), return RC_FAIL); - } - else - if (strcmp ((char *) child_node->name, "FunctionType") == 0) { - CHECK_FCT_DO(parse_function_type(child_node, head), return RC_FAIL); - } - } - } - } - - return RC_OK; -} - -static int free_elements(types_t *parent, int indent) { - types_t *cur_node = parent; - types_t *child_node; - - g_debug("%*s%p %s", indent, "", cur_node, cur_node->name != NULL ? cur_node->name : ""); - - for (; cur_node != NULL; cur_node = cur_node->next) { - if (cur_node->child != NULL) { - child_node = cur_node->child; - cur_node->child = NULL; /* Clear the child pointer to avoid re-processing it, we are handling a graph with loops */ - CHECK_FCT_DO(free_elements((child_node), indent + 2), return RC_FAIL); - } - } - free (cur_node); - - return RC_OK; -} - -int xml_parse_buffer(char *xml_buffer, const int size) { - xmlDocPtr doc; /* the resulting document tree */ - - if (xml_buffer == NULL) { - return RC_NULL_POINTER; - } - - if (xml_raw_data != NULL) - { - /* Free previous raw data */ - free (xml_raw_data); - } - xml_raw_data = xml_buffer; - xml_raw_data_size = size; - - if (xml_head != NULL) - { - /* Free previous definitions */ - free_elements(xml_head, 0); - - g_info("xml_parse_buffer freed previous definitions"); - } - - xml_head = NULL; - root = NULL; - messages_id_enum = NULL; - lte_time_type = NULL; - lte_time_frame_type = NULL; - lte_time_slot_type = NULL; - origin_task_id_type = NULL; - destination_task_id_type = NULL; - instance_type = NULL; - message_header_type = NULL; - message_type = NULL; - message_size_type = NULL; - - g_info("Parsing XML definition from buffer ..."); - - doc = xmlReadMemory(xml_buffer, size, NULL, NULL, 0); - - if (doc == NULL) { - g_warning("Failed to parse XML buffer: %s", xml_buffer); - ui_notification_dialog(GTK_MESSAGE_ERROR, FALSE, "parse messages format definition", "Fail to parse XML buffer"); - return RC_FAIL; - } - - return xml_parse_doc(doc); -} - -static int update_filters() { - types_t *types; - - ui_init_filters(FALSE, TRUE); - - types = messages_id_enum; - if (types != NULL) - { - types = types->child; - - while (types != NULL) - { - if (strcmp (types->name, "MESSAGES_ID_MAX") != 0) - { - ui_filters_add (FILTER_MESSAGES, types->init_value, types->name, ENTRY_ENABLED_UNDEFINED, NULL, NULL); - } - types = types->next; - } - } - - types = origin_task_id_type; - if (types != NULL) - { - types = types->child->child; - - while (types != NULL) { - if ((strcmp (types->name, "TASK_FIRST") != 0) && (strcmp (types->name, "TASK_MAX") != 0)) - { - ui_filters_add(FILTER_ORIGIN_TASKS, types->init_value, types->name, ENTRY_ENABLED_UNDEFINED, NULL, NULL); - } - types = types->next; - } - } - - types = destination_task_id_type; - if (types != NULL) - { - types = types->child->child; - - while (types != NULL) { - if ((strcmp (types->name, "TASK_FIRST") != 0) && (strcmp (types->name, "TASK_MAX") != 0)) - { - ui_filters_add(FILTER_DESTINATION_TASKS, types->init_value, types->name, ENTRY_ENABLED_UNDEFINED, NULL, NULL); - } - types = types->next; - } - } - - return RC_OK; -} - -static int xml_parse_doc(xmlDocPtr doc) { - xmlNode *root_element = NULL; - int ret = 0; - FILE *dissect_file = NULL; - - if (ui_main_data.dissect_file_name != NULL) { - dissect_file = fopen (ui_main_data.dissect_file_name, "w"); - } - - /* Get the root element node */ - root_element = xmlDocGetRootElement(doc); - - ret = parse_elements(root_element, &xml_head); - - /* Free the document */ - xmlFreeDoc(doc); - - if (ret == RC_OK) { - resolve_typedefs (&xml_head); - resolve_pointer_type (&xml_head); - resolve_field (&xml_head); - resolve_array (&xml_head); - resolve_reference (&xml_head); - resolve_struct (&xml_head); - resolve_file (&xml_head); - resolve_union (&xml_head); - resolve_function (&xml_head); - - /* Locate the root element which corresponds to the MessageDef struct */ - CHECK_FCT(locate_root("MessageDef", xml_head, &root)); - - /* Locate the LTE time fields */ - if (locate_type("lte_time", xml_head, <e_time_type) == RC_OK) - { - CHECK_FCT(locate_type("frame", lte_time_type->child->child, <e_time_frame_type)); - CHECK_FCT(locate_type("slot", lte_time_type->child->child, <e_time_slot_type)); - } - - /* Locate the message id field */ - CHECK_FCT(locate_type("MessagesIds", xml_head, &messages_id_enum)); - - /* Locate the header part of a message */ - CHECK_FCT(locate_type("ittiMsgHeader", xml_head, &message_header_type)); - /* Locate the main message part */ - CHECK_FCT(locate_type("ittiMsg", xml_head, &message_type)); - - /* Locate the origin task id field */ - CHECK_FCT(locate_type_children("originTaskId", message_header_type->child->child, &origin_task_id_type)); - /* Locate the destination task id field */ - CHECK_FCT(locate_type_children("destinationTaskId", message_header_type->child->child, &destination_task_id_type)); - /* Locate the instance field */ - CHECK_FCT(locate_type_children("instance", message_header_type->child->child, &instance_type)); - /* Locate the message size field */ - CHECK_FCT(locate_type_children("ittiMsgSize", message_header_type->child->child, &message_size_type)); - - // root->type_hr_display(root, 0); - - update_filters(); - if (dissect_file != NULL) { - g_debug("generating dissected types file \"%s\" ...", ui_main_data.dissect_file_name); - root->type_file_print (root, 0, dissect_file); - } - } - - if (dissect_file != NULL) { - fclose (dissect_file); - } - - g_message("Parsed XML definition"); - - return ret; -} - -int dissect_signal_header(buffer_t *buffer, ui_set_signal_text_cb_t ui_set_signal_text_cb, - gpointer cb_user_data) -{ - if (message_header_type == NULL) { - g_error("No messages format definition provided"); - return RC_FAIL; - } - - if (buffer == NULL) { - g_error("Failed buffer is NULL"); - return RC_FAIL; - } - - message_header_type->type_dissect_from_buffer( - message_header_type, ui_set_signal_text_cb, cb_user_data, - buffer, 0, 0, INDENT_START, TRUE); - - return RC_OK; -} - -int dissect_signal(buffer_t *buffer, ui_set_signal_text_cb_t ui_set_signal_text_cb, - gpointer cb_user_data) -{ - if (message_type == NULL) { - g_error("No messages format definition provided"); - return RC_FAIL; - } - - if (buffer == NULL) { - g_error("Failed buffer is NULL"); - return RC_FAIL; - } - - message_type->type_dissect_from_buffer(message_type, ui_set_signal_text_cb, cb_user_data, - buffer, 0, 0, INDENT_START, TRUE); - - return RC_OK; -} diff --git a/common/utils/itti_analyzer/libresolver/Makefile.am b/common/utils/itti_analyzer/libresolver/Makefile.am deleted file mode 100644 index 875fc81916..0000000000 --- a/common/utils/itti_analyzer/libresolver/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -AM_CFLAGS = \ - @ADD_CFLAGS@ \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libparser \ - -I$(top_srcdir)/libui \ - -I$(top_srcdir)/libbuffers - -noinst_LTLIBRARIES = libresolver.la - -libresolver_la_LDFLAGS = -all-static -libresolver_la_SOURCES = \ - locate_root.c locate_root.h \ - resolvers.c resolvers.h diff --git a/common/utils/itti_analyzer/libresolver/locate_root.c b/common/utils/itti_analyzer/libresolver/locate_root.c deleted file mode 100644 index dffd489944..0000000000 --- a/common/utils/itti_analyzer/libresolver/locate_root.c +++ /dev/null @@ -1,251 +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 - */ - -#include -#include - -#define G_LOG_DOMAIN ("RESOLVER") - -#include - -#include "logs.h" -#include "rc.h" - -#include "types.h" -#include "enum_type.h" -#include "locate_root.h" -#include "xml_parse.h" - -types_t *messages_id_enum; -types_t *lte_time_type; -types_t *lte_time_frame_type; -types_t *lte_time_slot_type; -types_t *origin_task_id_type; -types_t *destination_task_id_type; -types_t *instance_type; -types_t *message_header_type; -types_t *message_type; -types_t *message_size_type; - -int locate_root(const char *root_name, types_t *head, types_t **root_elm) { - types_t *next_type; - int next_counter = 0; - - /* The root element is for example : MessageDef. - * This element is the entry for other sub-types. - */ - if (!root_name || (strlen (root_name) == 0)) { - g_warning("FATAL: no root element name provided"); - return -1; - } - if (!head) { - g_warning("Empty list detected"); - return -1; - } - if (!root_elm) { - g_warning("NULL root reference"); - return -1; - } - - for (next_type = head; next_type; next_type = next_type->next) { - if (next_type->name == NULL) - continue; - if (strcmp (root_name, next_type->name) == 0) { - /* Matching reference */ - break; - } - next_counter ++; - } - g_info("locate_root: %s %d", root_name, next_counter); - - *root_elm = next_type; - return (next_type == NULL) ? -2 : 0; -} - -int locate_type(const char *type_name, types_t *head, types_t **type) { - types_t *next_type; - int next_counter = 0; - - /* The root element is for example : MessageDef. - * This element is the entry for other sub-types. - */ - if (!type_name) { - g_warning("FATAL: no element name provided"); - return RC_BAD_PARAM; - } - if (!head) { - g_warning("Empty list detected"); - return RC_BAD_PARAM; - } - - for (next_type = head; next_type; next_type = next_type->next) { - if (next_type->name == NULL) - continue; - if (strcmp (type_name, next_type->name) == 0) { - /* Matching reference */ - break; - } - next_counter ++; - } - g_info("locate_type: %s %d %p", type_name, next_counter, next_type); - - if (type) - *type = next_type; - return (next_type == NULL) ? RC_FAIL : RC_OK; -} - -int locate_type_children(const char *type_name, types_t *head, types_t **type) { - types_t *found_type = NULL; - int i; - - /* The root element is for example : MessageDef. - * This element is the entry for other sub-types. - */ - if (!type_name) { - g_warning("FATAL: no element name provided"); - return RC_BAD_PARAM; - } - if (!head) { - g_warning("Empty list detected"); - return RC_BAD_PARAM; - } - - for (i = 0; i < head->nb_members; i++) { - if (head->members_child[i]->name == NULL) - continue; - if (strcmp (type_name, head->members_child[i]->name) == 0) { - /* Matching reference */ - found_type = head->members_child[i]; - break; - } - } - g_info("locate_type: %s %d %p", type_name, i, found_type); - - if (type) - *type = found_type; - return (found_type == NULL) ? RC_FAIL : RC_OK; -} - -uint32_t get_message_header_type_size(void) -{ - /* Typedef */ - if (message_header_type->child != NULL) { - /* Struct */ - if (message_header_type->child->child != NULL) { - return message_header_type->child->child->size; - } - } - return 0; -} - -uint32_t get_message_size(buffer_t *buffer) -{ - uint32_t value = 0; - - if (message_size_type != NULL) - { - types_t *temp = message_size_type; - - while (temp->size == -1) { - temp = temp->child; - } - - /* Fetch instance value */ - buffer_fetch_bits (buffer, message_size_type->offset, temp->size, &value); - } - - return value; -} - -uint32_t get_lte_frame(buffer_t *buffer) { - uint32_t value = 0; - - if (lte_time_type !=NULL) - { - /* Fetch instance value */ - buffer_fetch_bits (buffer, lte_time_type->offset + lte_time_frame_type->offset, lte_time_frame_type->child->child->size, &value); - } - - return value; -} - -uint32_t get_lte_slot(buffer_t *buffer) { - uint32_t value = 0; - - if (lte_time_type !=NULL) - { - /* Fetch instance value */ - buffer_fetch_bits (buffer, lte_time_type->offset + lte_time_slot_type->offset, lte_time_slot_type->child->child->size, &value); - } - - return value; -} - -uint32_t get_message_id(types_t *head, buffer_t *buffer, uint32_t *message_id) { - uint32_t value; - - g_assert(message_id != NULL); - g_assert(buffer != NULL); - - /* MessageId is an offset from start of buffer */ - value = buffer_get_uint32_t(buffer, messages_id_enum->offset); - - *message_id = value; - return RC_OK; -} - -uint32_t get_task_id(buffer_t *buffer, types_t *task_id_type) { - uint32_t task_id_value; - - /* Fetch task id value */ - if (buffer_fetch_bits (buffer, task_id_type->offset, task_id_type->child->size, &task_id_value) != RC_OK) - { - return ~0; - } - - return task_id_value; -} - -char *task_id_to_string(uint32_t task_id_value, types_t *task_id_type) { - char *task_id = "UNKNOWN"; - - if (task_id_value < ((uint32_t) ~0)) - { - /* Search task id name */ - task_id = enum_type_get_name_from_value (task_id_type->child, task_id_value); - } - - return task_id; -} - -uint32_t get_instance(buffer_t *buffer) { - uint32_t instance_value; - - /* Fetch instance value */ - buffer_fetch_bits (buffer, instance_type->offset, instance_type->child->child->child->size, &instance_value); - - return instance_value; -} - -char *message_id_to_string(uint32_t message_id) -{ - return enum_type_get_name_from_value(messages_id_enum, message_id); -} diff --git a/common/utils/itti_analyzer/libresolver/locate_root.h b/common/utils/itti_analyzer/libresolver/locate_root.h deleted file mode 100644 index 5cb2eb2588..0000000000 --- a/common/utils/itti_analyzer/libresolver/locate_root.h +++ /dev/null @@ -1,62 +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 - */ - -#ifndef LOCATE_ROOT_H_ -#define LOCATE_ROOT_H_ - -#include "types.h" - -extern types_t *messages_id_enum; -extern types_t *lte_time_type; -extern types_t *lte_time_frame_type; -extern types_t *lte_time_slot_type; -extern types_t *origin_task_id_type; -extern types_t *destination_task_id_type; -extern types_t *instance_type; -extern types_t *message_header_type; -extern types_t *message_type; -extern types_t *message_size_type; - -int locate_root(const char *root_name, types_t *head, types_t **root); - -int locate_type(const char *type_name, types_t *head, types_t **type); - -int locate_type_children(const char *type_name, types_t *head, types_t **type); - -uint32_t get_message_header_type_size(void); - -uint32_t get_message_size(buffer_t *buffer); - -uint32_t get_lte_frame(buffer_t *buffer); - -uint32_t get_lte_slot(buffer_t *buffer); - -uint32_t get_message_id(types_t *head, buffer_t *buffer, uint32_t *message_id); - -char *message_id_to_string(uint32_t message_id); - -uint32_t get_task_id(buffer_t *buffer, types_t *task_id_type); - -char *task_id_to_string(uint32_t task_id_value, types_t *task_id_type); - -uint32_t get_instance(buffer_t *buffer); - -#endif /* LOCATE_ROOT_H_ */ diff --git a/common/utils/itti_analyzer/libresolver/resolvers.c b/common/utils/itti_analyzer/libresolver/resolvers.c deleted file mode 100644 index 8702c08942..0000000000 --- a/common/utils/itti_analyzer/libresolver/resolvers.c +++ /dev/null @@ -1,384 +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 - */ - -#include -#include -#include - -#define G_LOG_DOMAIN ("RESOLVER") - -#include - -#include "types.h" -#include "resolvers.h" - -typedef enum { - RESOLV_OK = 0, - RESOLV_ERROR = -1, - RESOLV_LIST_EMPTY = -2, - RESOLV_NOT_FOUND = -3, -} resolv_rc_e; - -static int search_id(types_t *head, types_t **found, int id) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = head; next_type; next_type = next_type->next) - { - if (next_type->id == id && next_type->type != TYPE_FILE) - break; - } - if (found) - *found = next_type; - - return next_type == NULL ? RESOLV_NOT_FOUND : RESOLV_OK; -} - -int search_file(types_t *head, types_t **found, int file_id) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = head; next_type; next_type = next_type->next) - { - if (next_type->type != TYPE_FILE) - continue; - if (file_id == next_type->id) - break; - } - if (found) - *found = next_type; - - return next_type == NULL ? RESOLV_NOT_FOUND : RESOLV_OK; -} - -int resolve_typedefs(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type != TYPE_TYPEDEF) - continue; - -// printf("Trying to resolve typedef %s with type %d\n", next_type->name, next_type->id); - - if (search_id(*head, &next_type->child, next_type->type_xml) != RESOLV_OK) { - /* We have to remove this reference */ - }/* else { - next_type->type_hr_display(next_type, 0); - }*/ - } - - return 0; -} - -int resolve_struct(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - char *member; - char *members; - - /* Only resolve typedef */ - if (next_type->type != TYPE_STRUCT) - continue; - - g_debug("Trying to resolve struct members %s with type %d", next_type->name, next_type->id); - - /* Struct may have no member */ - if (next_type->members == NULL) - continue; - - /* We have to copy the string as strtok will split the string in argument */ - members = strdup(next_type->members); - - /* Split the string on spaces and _ */ - member = strtok(members, " _"); - while(member != NULL) - { - if (next_type->nb_members == 0) { - next_type->members_child = malloc(sizeof(types_t *)); - } else { - next_type->members_child = realloc(next_type->members_child, - (next_type->nb_members + 1) * sizeof(types_t *)); - } - if (search_id(*head, &next_type->members_child[next_type->nb_members], atoi(member)) != RESOLV_OK) { - /* We have to remove this reference */ - } - if ((next_type->members_child[next_type->nb_members] != NULL) - && (next_type->members_child[next_type->nb_members]->type != TYPE_FIELD)) - { - /* Only keep field child for structure, other member can be present - * for defining types (union or struct) used by fields but should not be considered. */ - next_type->members_child[next_type->nb_members] = NULL; - /* We have to remove this reference */ - } - next_type->nb_members++; - /* Pick up the next string available */ - member = strtok(NULL, " _"); - } - - free(members); - } - - return 0; -} - -int resolve_union(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - char *member; - char *members; - - /* Only resolve typedef */ - if (next_type->type != TYPE_UNION) - continue; - - g_debug("Trying to resolve union members %s with type %d\n", next_type->name, next_type->id); - - /* Struct may have no member */ - if (next_type->members == NULL) - continue; - - /* We have to copy the string as strtok will modify the string in argument */ - members = strdup(next_type->members); - - /* Split the string on spaces and _ */ - member = strtok(members, " _"); - while(member != NULL) - { - if (next_type->nb_members == 0) { - next_type->members_child = malloc(sizeof(types_t *)); - } else { - next_type->members_child = realloc(next_type->members_child, - (next_type->nb_members + 1) * sizeof(types_t *)); - } - if (search_id(*head, &next_type->members_child[next_type->nb_members], atoi(member)) != RESOLV_OK) { - /* We have to remove this reference */ - } - next_type->nb_members++; - /* Pick up the next string available */ - member = strtok(NULL, " _"); - } - - free(members); - } - - return 0; -} - -int resolve_pointer_type(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type != TYPE_POINTER) - continue; - - g_debug("Trying to resolve pointer id %d with type %d", - next_type->id, next_type->type_xml); - - if (search_id(*head, &next_type->child, next_type->type_xml) != RESOLV_OK) { - /* We have to remove this reference */ - } -// next_type->type_hr_display(next_type, 0); - } - - return 0; -} - -int resolve_reference(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type != TYPE_REFERENCE) - continue; - - g_debug("Trying to resolve reference id %d with type %d\n", - next_type->id, next_type->type_xml); - - if (search_id(*head, &next_type->child, next_type->type_xml) != RESOLV_OK) { - /* We have to remove this reference */ - } -// next_type->type_hr_display(next_type, 0); - } - - return 0; -} - -int resolve_field(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type != TYPE_FIELD) - continue; - - g_debug("Trying to resolve pointer id %d with type %d\n", - next_type->id, next_type->type_xml); - - if (search_id(*head, &next_type->child, next_type->type_xml) != RESOLV_OK) { - /* We have to remove this reference */ - } -// next_type->type_hr_display(next_type, 0); - } - - return 0; -} - -int resolve_array(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type != TYPE_ARRAY) - continue; - - g_debug("Trying to resolve array id %d with type %d\n", - next_type->id, next_type->type_xml); - - if (search_id(*head, &next_type->child, next_type->type_xml) != RESOLV_OK) { - /* We have to remove this reference */ - } -// next_type->type_hr_display(next_type, 0); - } - - return 0; -} - -int resolve_function(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type != TYPE_FUNCTION) - continue; - - g_debug("Trying to resolve function id %d with type %d", - next_type->id, next_type->type_xml); - - if (search_id(*head, &next_type->child, next_type->type_xml) != RESOLV_OK) { - /* We have to remove this reference */ - } -// next_type->type_hr_display(next_type, 0); - } - - return 0; -} - -int resolve_file(types_t **head) -{ - types_t *next_type; - - if (!head) { - g_warning("Empty list detected"); - return RESOLV_LIST_EMPTY; - } - - for (next_type = *head; next_type; next_type = next_type->next) - { - /* Only resolve typedef */ - if (next_type->type == TYPE_FILE) - continue; - - /* No reference to a file */ - if (next_type->file == NULL) { - continue; - } - - g_debug("Trying to resolve file %s\n", next_type->file); - - if (search_file(*head, &next_type->file_ref, atoi(&next_type->file[1])) != RESOLV_OK) { - /* We have to remove this reference */ - } -// next_type->type_hr_display(next_type, 0); - } - - return 0; -} - diff --git a/common/utils/itti_analyzer/libui/Makefile.am b/common/utils/itti_analyzer/libui/Makefile.am deleted file mode 100644 index 4a0d88cb95..0000000000 --- a/common/utils/itti_analyzer/libui/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -AM_CFLAGS = \ - @ADD_CFLAGS@ \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/libbuffers \ - -I$(top_srcdir)/libparser \ - -I$(top_srcdir)/libresolver - -noinst_LTLIBRARIES = libui.la - -libui_la_LDFLAGS = -all-static -libui_la_SOURCES = \ - ui_main_screen.c ui_main_screen.h \ - ui_menu_bar.c ui_menu_bar.h \ - ui_callbacks.c ui_callbacks.h \ - ui_tree_view.c ui_tree_view.h \ - ui_signal_dissect_view.c ui_signal_dissect_view.h \ - ui_notifications.c ui_notifications.h \ - ui_notif_dlg.c ui_notif_dlg.h \ - ui_interface.c ui_interface.h \ - ui_notebook.c ui_notebook.h \ - ui_filters.c ui_filters.h \ No newline at end of file diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.c b/common/utils/itti_analyzer/libui/ui_callbacks.c deleted file mode 100644 index 6fc480e333..0000000000 --- a/common/utils/itti_analyzer/libui/ui_callbacks.c +++ /dev/null @@ -1,983 +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 - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#define G_LOG_DOMAIN ("UI_CB") - -#include - -#include "logs.h" -#include "rc.h" - -#include "socket.h" - -#include "ui_notif_dlg.h" -#include "ui_main_screen.h" -#include "ui_menu_bar.h" -#include "ui_callbacks.h" -#include "ui_interface.h" -#include "ui_notifications.h" -#include "ui_tree_view.h" -#include "ui_signal_dissect_view.h" -#include "ui_filters.h" -#include "ui_notebook.h" - -#include "types.h" -#include "locate_root.h" -#include "xml_parse.h" - -static gboolean refresh_message_list = TRUE; -static gboolean filters_changed = FALSE; -static gboolean operation_running = FALSE; - -static const char *ui_ip; -static uint16_t ui_port; -static GtkWidget *dialogbox_connect; -static gboolean ui_auto_reconnect; - -gboolean ui_callback_on_open_messages(GtkWidget *widget, gpointer data) -{ - gboolean refresh = (data != NULL) ? TRUE : FALSE; - - g_message("Open messages event occurred %d", refresh); - - if (operation_running == FALSE) - { - operation_running = TRUE; - if (refresh && (ui_main_data.messages_file_name != NULL)) - { - ui_messages_read (ui_main_data.messages_file_name); - } - else - { - ui_messages_open_file_chooser (); - } - operation_running = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_on_save_messages(GtkWidget *widget, gpointer data) -{ - gboolean filtered = (data != NULL) ? TRUE : FALSE; - - g_message("Save messages event occurred %d", filtered); - - if (operation_running == FALSE) - { - operation_running = TRUE; - ui_messages_save_file_chooser(filtered); - operation_running = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_on_filters_enabled(GtkToolButton *button, gpointer data) -{ - gboolean enabled; - gboolean changed; - - enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(button)); - - g_info("Filters enabled event occurred %d", enabled); - - changed = ui_filters_enable (enabled); - - if (changed) - { - /* Set the tool tip text */ - if (enabled) - { - gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(button), "Disable messages filtering"); - } - else - { - gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(button), "Enable messages filtering"); - } - ui_tree_view_refilter (); - } - - return TRUE; -} - -gboolean ui_callback_on_open_filters(GtkWidget *widget, gpointer data) -{ - gboolean refresh = (data != NULL) ? TRUE : FALSE; - - g_message("Open filters event occurred"); - - if (operation_running == FALSE) - { - operation_running = TRUE; - if (refresh && (ui_main_data.filters_file_name != NULL)) - { - ui_filters_read (ui_main_data.filters_file_name); - } - else - { - ui_filters_open_file_chooser (); - } - operation_running = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_on_save_filters(GtkWidget *widget, gpointer data) -{ - if (operation_running == FALSE) - { - operation_running = TRUE; - g_message("Save filters event occurred"); - ui_filters_save_file_chooser(); - operation_running = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_on_enable_filters(GtkWidget *widget, gpointer data) -{ - gboolean enabled; - - enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.filters_enabled)); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.filters_enabled), !enabled); - - return TRUE; -} - -gboolean ui_callback_on_about(GtkWidget *widget, gpointer data) -{ -#if defined(PACKAGE_STRING) - ui_notification_dialog (GTK_MESSAGE_INFO, FALSE, "about", "Eurecom %s", PACKAGE_STRING); -#else - ui_notification_dialog (GTK_MESSAGE_INFO, FALSE, "about", "Eurecom itti_analyzer"); -#endif - - return TRUE; -} - -gint ui_callback_check_string (const char *string, const gint lenght, const guint message_number) -{ - gint real_length; - - real_length = strnlen (string, lenght); - if (lenght != real_length) - { - if (message_number) - { - g_warning("Bad string format for message %u, '\\0' found before end of string (%d/%d)\n", message_number, real_length, lenght); - } - else - { - g_warning("Bad string format, '\\0' found before end of string (%d/%d)\n", real_length, lenght); - } - return (real_length); - } - else - { - return (lenght); - } -} - -gboolean ui_callback_on_select_signal(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, - gboolean path_currently_selected, gpointer user_data) -{ - static gpointer buffer_current; - ui_text_view_t *text_view; - GtkTreeIter iter; - - g_debug("Message selected %d %p %p %s", path_currently_selected, buffer_current, path, gtk_tree_path_to_string(path)); - - if (!path_currently_selected) - { - text_view = (ui_text_view_t *) user_data; - - g_assert(text_view != NULL); - - if (gtk_tree_model_get_iter (model, &iter, path)) - { - gpointer buffer; - - uint32_t message_number; - uint32_t message_id; - uint32_t origin_task_id; - uint32_t destination_task_id; - char *instance_name; - uint32_t instance; - char label[100]; - - gtk_tree_model_get (model, &iter, COL_MSG_NUM, &message_number, COL_MESSAGE_ID, &message_id, - COL_FROM_TASK_ID, &origin_task_id, COL_TO_TASK_ID, &destination_task_id, COL_INSTANCE, &instance_name, - COL_INSTANCE_ID, &instance, COL_BUFFER, &buffer, -1); - - g_debug(" Get iter %p %p", buffer_current, buffer); - - if (ui_tree_view_last_event) - { - g_debug("last_event %p %d %d", ui_tree_view_last_event, ui_tree_view_last_event->type, ui_tree_view_last_event->button); - - if (ui_tree_view_last_event->type == GDK_BUTTON_PRESS) - { - /* Callback is due to a button click */ - if (ui_tree_view_last_event->button == 1) - { - /* It was a left mouse click */ - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE); - } - - if (ui_tree_view_last_event->button == 3) - { - /* It was a right mouse click */ - int item; - - /* Clear event */ - ui_tree_view_last_event = NULL; - - /* Create filter menus to refers its items in the pop-up menu */ - ui_create_filter_menus (); - - g_info("Message selected right click %d %d %d %d", message_id, origin_task_id, destination_task_id, instance); - - /* Message Id menu */ - { - /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */ - ui_tree_view_menu_enable[MENU_MESSAGE].filter_item = NULL; - item = ui_filters_search_id (&ui_filters.messages, message_id); - /* Update the menu item check state based on message ID state */ - gtk_check_menu_item_set_active ( - GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_MESSAGE].menu_enable), - ui_filters.messages.items[item].enabled); - /* Set menu item label */ - sprintf (label, "Message: %s", message_id_to_string (message_id)); - gtk_menu_item_set_label (GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_MESSAGE].menu_enable), - label); - /* Save menu item associated to this row */ - ui_tree_view_menu_enable[MENU_MESSAGE].filter_item = &ui_filters.messages.items[item]; - } - - /* Origin task id */ - { - /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */ - ui_tree_view_menu_enable[MENU_FROM_TASK].filter_item = NULL; - item = ui_filters_search_id (&ui_filters.origin_tasks, origin_task_id); - /* Update the menu item check state based on message ID state */ - gtk_check_menu_item_set_active ( - GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_FROM_TASK].menu_enable), - ui_filters.origin_tasks.items[item].enabled); - /* Set menu item label */ - sprintf (label, "From: %s", task_id_to_string (origin_task_id, origin_task_id_type)); - gtk_menu_item_set_label ( - GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_FROM_TASK].menu_enable), label); - /* Save menu item associated to this row */ - ui_tree_view_menu_enable[MENU_FROM_TASK].filter_item = &ui_filters.origin_tasks.items[item]; - } - - /* Destination task id */ - { - /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */ - ui_tree_view_menu_enable[MENU_TO_TASK].filter_item = NULL; - item = ui_filters_search_id (&ui_filters.destination_tasks, destination_task_id); - /* Update the menu item check state based on message ID state */ - gtk_check_menu_item_set_active ( - GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_TO_TASK].menu_enable), - ui_filters.destination_tasks.items[item].enabled); - /* Set menu item label */ - sprintf (label, "To: %s", - task_id_to_string (destination_task_id, destination_task_id_type)); - gtk_menu_item_set_label (GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_TO_TASK].menu_enable), - label); - /* Save menu item associated to this row */ - ui_tree_view_menu_enable[MENU_TO_TASK].filter_item = - &ui_filters.destination_tasks.items[item]; - } - - /* Instance */ - { - /* Invalidate associated menu item to avoid issue with call back when updating the menu item check state */ - ui_tree_view_menu_enable[MENU_INSTANCE].filter_item = NULL; - item = ui_filters_search_id (&ui_filters.instances, instance); - /* Update the menu item check state based on message ID state */ - gtk_check_menu_item_set_active ( - GTK_CHECK_MENU_ITEM(ui_tree_view_menu_enable[MENU_INSTANCE].menu_enable), - ui_filters.instances.items[item].enabled); - /* Set menu item label */ - sprintf (label, "Instance: %s", instance_name); - gtk_menu_item_set_label (GTK_MENU_ITEM(ui_tree_view_menu_enable[MENU_INSTANCE].menu_enable), - label); - /* Save menu item associated to this row */ - ui_tree_view_menu_enable[MENU_INSTANCE].filter_item = &ui_filters.instances.items[item]; - } - - gtk_menu_popup (GTK_MENU (ui_tree_view_menu), NULL, NULL, NULL, NULL, 0, - gtk_get_current_event_time ()); - } - } - - /* Clear event */ - ui_tree_view_last_event = NULL; - } - - if (buffer_current != buffer) - { - buffer_current = buffer; - - /* Clear the view */ - CHECK_FCT_DO(ui_signal_dissect_clear_view(text_view), return FALSE); - - if (ui_main_data.display_message_header) - { - CHECK_FCT_DO(dissect_signal_header((buffer_t*)buffer, ui_signal_set_text, text_view), return FALSE); - } - - if ((strcmp (message_id_to_string (message_id), "ERROR_LOG") == 0) - || (strcmp (message_id_to_string (message_id), "WARNING_LOG") == 0) - || (strcmp (message_id_to_string (message_id), "NOTICE_LOG") == 0) - || (strcmp (message_id_to_string (message_id), "INFO_LOG") == 0) - || (strcmp (message_id_to_string (message_id), "DEBUG_LOG") == 0) - || (strcmp (message_id_to_string (message_id), "GENERIC_LOG") == 0)) - { - gchar *data; - gint data_size; - uint32_t message_header_type_size; - - if (ui_main_data.display_message_header) - { - ui_signal_set_text (text_view, "\n", 1); - } - - message_header_type_size = get_message_header_type_size (); - data = (gchar *) buffer_at_offset ((buffer_t*) buffer, message_header_type_size); - data_size = get_message_size ((buffer_t*) buffer); - data_size = ui_callback_check_string (data, data_size, message_number); - - g_info(" dump message %d: header type size: %u, data size: %u, buffer %p, follow last %d", - message_number, message_header_type_size, data_size, buffer, ui_main_data.follow_last); - - ui_signal_set_text (text_view, data, data_size); - } - else - { - g_info(" dissect message %d: id %d, buffer %p, follow last %d", message_number, message_id, buffer, ui_main_data.follow_last); - - /* Dissect the signal */ - CHECK_FCT_DO(dissect_signal((buffer_t*)buffer, ui_signal_set_text, text_view), return FALSE); - } - } - } - } - return TRUE; -} - -gboolean ui_callback_on_menu_enable(GtkWidget *widget, gpointer data) -{ - ui_tree_view_menu_enable_t *menu_enable = data; - - if (menu_enable->filter_item != NULL) - { - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_enable->filter_item->menu_item), - gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(menu_enable->menu_enable))); - menu_enable->filter_item = NULL; - } - - return TRUE; -} - -gboolean ui_callback_on_menu_color(GtkWidget *widget, gpointer data) -{ - ui_tree_view_menu_color_t *menu_color = data; - - GdkRGBA color; - GtkWidget *color_chooser; - gint response; - - color_chooser = gtk_color_chooser_dialog_new ("Select message background color", GTK_WINDOW(ui_main_data.window)); - gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER(color_chooser), FALSE); - response = gtk_dialog_run (GTK_DIALOG (color_chooser)); - - if (response == GTK_RESPONSE_OK) - { - int red, green, blue; - char *color_string; - - color_string = - menu_color->foreground ? - menu_color->menu_enable->filter_item->foreground : - menu_color->menu_enable->filter_item->background; - - gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER(color_chooser), &color); - - red = (int) (color.red * 255); - green = (int) (color.green * 255); - blue = (int) (color.blue * 255); - - snprintf (color_string, COLOR_SIZE, "#%02x%02x%02x", red, green, blue); - ui_tree_view_refilter (); - - g_info("Selected color for %s %f->%02x %f->%02x %f->%02x %s", - menu_color->menu_enable->filter_item->name, color.red, red, color.green, green, color.blue, blue, color_string); - } - gtk_widget_destroy (color_chooser); - - return TRUE; -} - -void ui_signal_add_to_list(gpointer data, gpointer user_data) -{ - gboolean goto_last = user_data ? TRUE : FALSE; - buffer_t *signal_buffer; - GtkTreePath *path; - GtkTreeViewColumn *focus_column; - uint32_t lte_frame; - uint32_t lte_slot; - uint32_t origin_task_id; - uint32_t destination_task_id; - uint32_t instance; - char lte_time[15]; - - g_assert(data != NULL); - g_assert(origin_task_id_type != NULL); - g_assert(destination_task_id_type != NULL); - - gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), &path, &focus_column); - - signal_buffer = (buffer_t *) data; - - lte_frame = get_lte_frame (signal_buffer); - lte_slot = get_lte_slot (signal_buffer); - sprintf (lte_time, "%d.%02d", lte_frame, lte_slot); - - get_message_id (root, signal_buffer, &signal_buffer->message_id); - origin_task_id = get_task_id (signal_buffer, origin_task_id_type); - destination_task_id = get_task_id (signal_buffer, destination_task_id_type); - instance = get_instance (signal_buffer); - - ui_tree_view_new_signal_ind (signal_buffer->message_number, lte_time, signal_buffer->message_id, - message_id_to_string (signal_buffer->message_id), origin_task_id, - task_id_to_string (origin_task_id, origin_task_id_type), destination_task_id, - task_id_to_string (destination_task_id, destination_task_id_type), instance, data); - - if ((strcmp (message_id_to_string (signal_buffer->message_id), "ERROR_LOG") == 0) - || (strcmp (message_id_to_string (signal_buffer->message_id), "WARNING_LOG") == 0) - || (strcmp (message_id_to_string (signal_buffer->message_id), "NOTICE_LOG") == 0) - || (strcmp (message_id_to_string (signal_buffer->message_id), "INFO_LOG") == 0) - || (strcmp (message_id_to_string (signal_buffer->message_id), "DEBUG_LOG") == 0) - || (strcmp (message_id_to_string (signal_buffer->message_id), "GENERIC_LOG") == 0)) - { - gchar *string_terminal; - gint string_terminal_size; - uint32_t message_header_type_size; - - message_header_type_size = get_message_header_type_size (); - string_terminal = (gchar *) buffer_at_offset ((buffer_t*) signal_buffer, message_header_type_size); - string_terminal_size = get_message_size ((buffer_t*) signal_buffer); - string_terminal_size = ui_callback_check_string (string_terminal, string_terminal_size, signal_buffer->message_number); - ui_notebook_terminal_append_data(string_terminal, string_terminal_size); - } - - /* Increment number of messages */ - ui_main_data.nb_message_received++; - - if ((ui_main_data.follow_last) && (goto_last)) - { - /* Advance to the new last signal */ - ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1); - } -} - -static gboolean ui_handle_update_signal_list(gint fd, void *data, size_t data_length) -{ - pipe_new_signals_list_message_t *signal_list_message; - - /* Enable buttons to move in the list of signals */ - ui_set_sensitive_move_buttons (TRUE); - - signal_list_message = (pipe_new_signals_list_message_t *) data; - - g_assert(signal_list_message != NULL); - g_assert(signal_list_message->signal_list != NULL); - - g_list_foreach (signal_list_message->signal_list, ui_signal_add_to_list, (gpointer) TRUE); - - /* Free the list but not user data associated with each element */ - g_list_free (signal_list_message->signal_list); - /* Free the message */ - free (signal_list_message); - - ui_gtk_flush_events (); - - return TRUE; -} - -static gboolean ui_handle_socket_connection_failed(gint fd) -{ - gtk_dialog_response(GTK_DIALOG (dialogbox_connect), GTK_RESPONSE_REJECT); - - return TRUE; -} - -static gboolean ui_handle_socket_connection_lost(gint fd) -{ - if (operation_running) - { - operation_running = FALSE; - if (ui_auto_reconnect) - { - ui_callback_on_connect (NULL, (gpointer) FALSE); - } - else - { - ui_enable_connect_button(); - ui_set_sensitive_save_message_buttons (TRUE); - } - } - - return TRUE; -} - -static gboolean ui_handle_socket_xml_definition(gint fd, void *data, size_t data_length) -{ - pipe_xml_definition_message_t *xml_definition_message; - - xml_definition_message = (pipe_xml_definition_message_t *) data; - g_assert(xml_definition_message != NULL); - g_assert(data_length == sizeof(pipe_xml_definition_message_t)); - - xml_parse_buffer (xml_definition_message->xml_definition, xml_definition_message->xml_definition_length); - - return TRUE; -} - -gboolean ui_pipe_callback(gint source, gpointer user_data) -{ - void *input_data = NULL; - size_t input_data_length = 0; - pipe_input_header_t input_header; - - /* Read the header */ - if (read (source, &input_header, sizeof(input_header)) < 0) - { - g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno)); - return FALSE; - } - - input_data_length = input_header.message_size - sizeof(input_header); - - /* Checking for non-header part */ - if (input_data_length > 0) - { - input_data = malloc (input_data_length); - - if (read (source, input_data, input_data_length) < 0) - { - g_warning("Failed to read from pipe %d: %s", source, g_strerror(errno)); - return FALSE; - } - } - - switch (input_header.message_type) - { - case UI_PIPE_CONNECTION_FAILED: - return ui_handle_socket_connection_failed (source); - - case UI_PIPE_CONNECTION_LOST: - return ui_handle_socket_connection_lost (source); - - case UI_PIPE_XML_DEFINITION: - gtk_dialog_response(GTK_DIALOG (dialogbox_connect), GTK_RESPONSE_OK); - return ui_handle_socket_xml_definition (source, input_data, input_data_length); - - case UI_PIPE_UPDATE_SIGNAL_LIST: - return ui_handle_update_signal_list (source, input_data, input_data_length); - - default: - g_warning("[gui] Unhandled message type %u", input_header.message_type); - g_assert_not_reached(); - } - return FALSE; -} - -gboolean ui_callback_on_auto_reconnect(GtkWidget *widget, gpointer data) -{ - gboolean enabled; - gboolean changed = TRUE; - - gboolean toggle = (data != NULL) ? TRUE : FALSE; - - enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.auto_reconnect)); - - if (toggle) - { - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.auto_reconnect), !enabled); - return TRUE; - } - - g_info("Auto reconnect event occurred %d %d ", toggle, enabled); - - ui_auto_reconnect = enabled; - - if (changed) - { - /* Set the tool tip text */ - if (enabled) - { - gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(ui_main_data.auto_reconnect), "Disable automatic reconnection"); - } - else - { - gtk_tool_item_set_tooltip_text (GTK_TOOL_ITEM(ui_main_data.auto_reconnect), "Enable automatic reconnection"); - } - } - - return TRUE; -} - -void ui_callback_dialogbox_connect_destroy(void) -{ - if (dialogbox_connect != NULL) - { - gtk_widget_destroy (dialogbox_connect); - dialogbox_connect = NULL; - g_message("Connect dialogbox destroyed"); - } -} - -gboolean ui_callback_on_connect(GtkWidget *widget, gpointer data) -{ - /* We have to retrieve the ip address and ui_port of remote host */ - gboolean start = (data != NULL) ? TRUE : FALSE; - int pipe_fd[2]; - - if (start) - { - ui_port = atoi (gtk_entry_get_text (GTK_ENTRY(ui_main_data.port_entry))); - ui_ip = gtk_entry_get_text (GTK_ENTRY(ui_main_data.ip_entry)); - } - - g_message("Connect event occurred to %s:%d %s", ui_ip, ui_port, start ? "START" : "RETRY"); - - if (start) - { - if (strlen (ui_ip) == 0) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Connect", "Empty host ip address"); - return FALSE; - } - - if (ui_port == 0) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Connect", "Invalid host ui_port value"); - return FALSE; - } - } - - if (operation_running == FALSE) - { - operation_running = TRUE; - - ui_pipe_new (pipe_fd, ui_pipe_callback, NULL); - - memcpy (ui_main_data.pipe_fd, pipe_fd, sizeof(int) * 2); - - /* Disable the connect button */ - ui_disable_connect_button (); - - ui_set_title ("connecting to %s:%d ...", ui_ip, ui_port); - { - const static char *message_formats[] = - { - "Connecting to %s:%d ...", - "Connection lost!\n\n" "Trying to reconnect to %s:%d ..." - }; - gint response; - gint x, y; - gint w, h; - - if (socket_connect_to_remote_host (ui_ip, ui_port, pipe_fd[1]) != 0) - { - ui_enable_connect_button (); - operation_running = FALSE; - return FALSE; - } - - /* Create dialog box for connect message: - * - non modal mode does not seems to work, don't set the parent window to allow some interactions with it! - */ - dialogbox_connect = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER, - GTK_BUTTONS_CANCEL, message_formats[start ? 0 : 1], ui_ip, ui_port); - gtk_window_set_title (GTK_WINDOW(dialogbox_connect), "Connect"); - - /* Set the window at center of main window manually as there is no parent defined */ - gtk_window_get_position (GTK_WINDOW(ui_main_data.window), &x, &y); - gtk_window_get_size (GTK_WINDOW(ui_main_data.window), &w, &h); - g_message("Main window position: %d,%d dimension: %d,%d", x, y, w, h); - x += w / 2; - y += h / 2; - g_message("Connect window position %d,%d", x, y); - gtk_window_set_gravity (GTK_WINDOW(dialogbox_connect), GDK_GRAVITY_CENTER); - gtk_window_move (GTK_WINDOW(dialogbox_connect), x, y); - - response = gtk_dialog_run (GTK_DIALOG (dialogbox_connect)); - g_message("Connect dialog response %s (%d)", gtk_get_respose_string(response), response); - - if (response == GTK_RESPONSE_NONE) - { - /* Dialogbox has been destroyed when program is exited, do nothing */ - return (TRUE); - } - if (response == GTK_RESPONSE_OK) - { - /* Connection is established */ - ui_set_sensitive_save_message_buttons (FALSE); - ui_callback_signal_clear_list (NULL, NULL); - ui_set_title ("%s:%d", ui_ip, ui_port); - } - else - { - /* Connection can not be established */ - if (response == GTK_RESPONSE_REJECT) - { - /* Connection retry time-out */ - ui_notification_dialog (GTK_MESSAGE_WARNING, FALSE, "Connect", "Failed to connect to provided host/ip address"); - } - - /* Re-enable connect button */ - ui_enable_connect_button(); - operation_running = FALSE; - } - ui_callback_dialogbox_connect_destroy (); - } - } - - return TRUE; -} - -gboolean ui_callback_on_disconnect(GtkWidget *widget, gpointer data) -{ - g_message("Disconnect event occurred"); - - ui_pipe_write_message (ui_main_data.pipe_fd[0], UI_PIPE_DISCONNECT_EVT, NULL, 0); - - if (dialogbox_connect != NULL) - { - gtk_dialog_response(GTK_DIALOG (dialogbox_connect), GTK_RESPONSE_CLOSE); - } - else - { - ui_enable_connect_button (); - operation_running = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_signal_go_to_first(GtkWidget *widget, gpointer data) -{ - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE); - ui_tree_view_select_row (0); - - return TRUE; -} - -gboolean ui_callback_signal_go_to(GtkWidget *widget, gpointer data) -{ - gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.signals_go_to_entry); - return TRUE; -} - -gboolean ui_callback_signal_go_to_entry(GtkWidget *widget, gpointer data) -{ - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), FALSE); - // gtk_entry_buffer_set_text(GTK_ENTRY(ui_main_data.signals_go_to_entry), ""); - gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.messages_list); - return TRUE; -} - -gboolean ui_callback_signal_go_to_last(GtkWidget *widget, gpointer data) -{ - gboolean enable = (data != NULL) ? TRUE : FALSE; - gboolean enabled; - - if (enable) - { - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), TRUE); - return TRUE; - } - - enabled = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button)); - - g_info("Button signal go to last event occurred %d %d", enable, enabled); - - if (enabled) - { - ui_main_data.follow_last = TRUE; - ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1); - } - else - { - ui_main_data.follow_last = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_display_message_header(GtkWidget *widget, gpointer data) -{ - ui_main_data.display_message_header = !ui_main_data.display_message_header; - // TODO refresh textview. - return TRUE; -} - -gboolean ui_callback_display_brace(GtkWidget *widget, gpointer data) -{ - ui_main_data.display_brace = !ui_main_data.display_brace; - // TODO refresh textview. - return TRUE; -} - -gboolean ui_callback_signal_clear_list(GtkWidget *widget, gpointer data) -{ - /* Disable buttons to move in the list of signals */ - ui_set_sensitive_move_buttons (FALSE); - ui_set_title (""); - - /* Clear list of signals */ - ui_tree_view_destroy_list (ui_main_data.messages_list); - - if (ui_main_data.text_view != NULL) - { - ui_signal_dissect_clear_view (ui_main_data.text_view); - } - - ui_notebook_terminal_clear(); - - return TRUE; -} - -static void ui_callback_on_menu_items_selected(GtkWidget *widget, gpointer data) -{ - gboolean active = data != NULL; - - if (GTK_IS_CHECK_MENU_ITEM(widget)) - { - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(widget), active); - } -} - -gboolean ui_callback_on_menu_none(GtkWidget *widget, gpointer data) -{ - GtkWidget *menu = (GtkWidget *) data; - - g_info("ui_callback_on_menu_none occurred %lx %lx)", (long) widget, (long) data); - - refresh_message_list = FALSE; - gtk_container_foreach (GTK_CONTAINER(menu), ui_callback_on_menu_items_selected, (gpointer) FALSE); - refresh_message_list = TRUE; - - if (filters_changed) - { - ui_tree_view_refilter (); - filters_changed = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_on_menu_all(GtkWidget *widget, gpointer data) -{ - GtkWidget *menu = (GtkWidget *) data; - - g_info("ui_callback_on_menu_all occurred %lx %lx)", (long) widget, (long) data); - - refresh_message_list = FALSE; - gtk_container_foreach (GTK_CONTAINER(menu), ui_callback_on_menu_items_selected, (gpointer) TRUE); - refresh_message_list = TRUE; - - if (filters_changed) - { - ui_tree_view_refilter (); - filters_changed = FALSE; - } - - return TRUE; -} - -gboolean ui_callback_on_menu_item_selected(GtkWidget *widget, gpointer data) -{ - ui_filter_item_t *filter_entry = data; - gboolean enabled; - - enabled = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM(widget)); - if (filter_entry->enabled != enabled) - { - filter_entry->enabled = enabled; - if (refresh_message_list) - { - ui_tree_view_refilter (); - } - else - { - filters_changed = TRUE; - } - } - g_info("ui_callback_on_menu_item_selected occurred %p %p %s %d (%d messages to display)", widget, data, filter_entry->name, enabled, ui_tree_view_get_filtered_number()); - - return TRUE; -} - -gboolean ui_callback_on_tree_column_header_click(GtkWidget *widget, gpointer data) -{ - col_type_t col = (col_type_t) data; - - g_info("ui_callback_on_tree_column_header_click %d", col); - switch (col) - { - case COL_MESSAGE: - ui_show_filter_menu (&ui_main_data.menu_filter_messages, &ui_filters.messages); - break; - - case COL_FROM_TASK: - ui_show_filter_menu (&ui_main_data.menu_filter_origin_tasks, &ui_filters.origin_tasks); - break; - - case COL_TO_TASK: - ui_show_filter_menu (&ui_main_data.menu_filter_destination_tasks, &ui_filters.destination_tasks); - break; - - case COL_INSTANCE: - ui_show_filter_menu (&ui_main_data.menu_filter_instances, &ui_filters.instances); - break; - - default: - g_warning("Unknown column filter %d in call to ui_callback_on_tree_column_header_click", col); - return FALSE; - } - - return TRUE; -} diff --git a/common/utils/itti_analyzer/libui/ui_callbacks.h b/common/utils/itti_analyzer/libui/ui_callbacks.h deleted file mode 100644 index b3d4b31c60..0000000000 --- a/common/utils/itti_analyzer/libui/ui_callbacks.h +++ /dev/null @@ -1,114 +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 - */ - -#ifndef UI_CALLBACKS_H_ -#define UI_CALLBACKS_H_ - -#include - -gboolean ui_callback_on_open_messages(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_save_messages(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_filters_enabled(GtkToolButton *button, - gpointer data); - -gboolean ui_callback_on_open_filters(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_save_filters(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_enable_filters(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_about(GtkWidget *widget, - gpointer data); - -gint ui_callback_check_string (const char *string, - const gint lenght, - const guint message_number); - -gboolean ui_pipe_callback(gint source, gpointer user_data); - -gboolean ui_callback_on_auto_reconnect(GtkWidget *widget, - gpointer data); - -void ui_callback_dialogbox_connect_destroy(void); - -gboolean ui_callback_on_connect(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_disconnect(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_tree_view_select(GtkWidget *widget, - GdkEvent *event, - gpointer data); - -gboolean ui_callback_on_select_signal(GtkTreeSelection *selection, - GtkTreeModel *model, - GtkTreePath *path, - gboolean path_currently_selected, - gpointer userdata); - -void ui_signal_add_to_list(gpointer data, - gpointer user_data); - -gboolean ui_callback_on_menu_enable (GtkWidget *widget, gpointer data); - -gboolean ui_callback_on_menu_color (GtkWidget *widget, gpointer data); - -gboolean ui_callback_signal_go_to_first(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_signal_go_to(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_signal_go_to_entry(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_signal_go_to_last(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_display_message_header(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_display_brace(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_signal_clear_list(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_menu_none(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_menu_all(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_menu_item_selected(GtkWidget *widget, - gpointer data); - -gboolean ui_callback_on_tree_column_header_click(GtkWidget *widget, - gpointer data); -#endif /* UI_CALLBACKS_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_filters.c b/common/utils/itti_analyzer/libui/ui_filters.c deleted file mode 100644 index 8a6321a538..0000000000 --- a/common/utils/itti_analyzer/libui/ui_filters.c +++ /dev/null @@ -1,609 +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 - */ - -#include -#include - -#define G_LOG_DOMAIN ("UI_FILTER") - -#include - -#include -#include - -#include "ui_callbacks.h" -#include "ui_main_screen.h" -#include "ui_filters.h" -#include "ui_tree_view.h" -#include "ui_notif_dlg.h" -#include "rc.h" - -const uint32_t FILTER_ALLOC_NUMBER = 100; -const uint32_t FILTER_ID_UNDEFINED = ~0; - -const char * const COLOR_WHITE = "#ffffff"; -const char * const COLOR_DARK_GREY = "#585858"; - -#define ENABLED_NAME "enabled" -#define FOREGROUND_NAME "foreground_color" -#define BACKGROUND_NAME "background_color" - -ui_filters_t ui_filters; - -static int ui_init_filter(ui_filter_t *filter, int reset, int clear_ids, char *name) -{ - if (filter->items == NULL) - { - filter->name = name; - - /* Allocate some filter entries */ - filter->items = malloc (FILTER_ALLOC_NUMBER * sizeof(ui_filter_item_t)); - filter->allocated = FILTER_ALLOC_NUMBER; - } - if (reset) - { - /* Reset number of used filter entries */ - filter->used = 0; - } - else - { - if (clear_ids) - { - /* Clear entries IDs */ - int item; - - for (item = 0; item < filter->used; item++) - { - filter->items[item].id = FILTER_ID_UNDEFINED; - } - } - } - - return (RC_OK); -} - -int ui_init_filters(int reset, int clear_ids) -{ - ui_init_filter (&ui_filters.messages, reset, clear_ids, "messages"); - ui_init_filter (&ui_filters.origin_tasks, reset, clear_ids, "origin_tasks"); - ui_init_filter (&ui_filters.destination_tasks, reset, clear_ids, "destination_tasks"); - ui_init_filter (&ui_filters.instances, reset, clear_ids, "instances"); - - ui_destroy_filter_menus (); - - return (RC_OK); -} - -gboolean ui_filters_enable(gboolean enabled) -{ - gboolean changed = ui_filters.filters_enabled != enabled; - - if (changed) - { - ui_filters.filters_enabled = enabled; - } - - return changed; -} - -static int ui_filters_search_name(ui_filter_t *filter, const char *name) -{ - int item; - - for (item = 0; item < filter->used; item++) - { - if (strncmp (name, filter->items[item].name, SIGNAL_NAME_LENGTH) == 0) - { - return (item); - } - } - - return (item); -} - -int ui_filters_search_id(ui_filter_t *filter, uint32_t value) -{ - int item; - - for (item = 0; item < filter->used; item++) - { - if (filter->items[item].id == value) - { - return (item); - } - } - - return (-1); -} - -static void ui_filter_set_enabled(uint8_t *enabled, ui_entry_enabled_e entry_enabled, gboolean new) -{ - if (entry_enabled == ENTRY_ENABLED_UNDEFINED) - { - if (new) - { - *enabled = TRUE; - } - } - else - { - if (entry_enabled == ENTRY_ENABLED_FALSE) - { - *enabled = FALSE; - } - else - { - *enabled = TRUE; - } - } -} - -static int ui_filter_add(ui_filter_t *filter, uint32_t value, const char *name, ui_entry_enabled_e entry_enabled, - const char *foreground, const char *background) -{ - int item = ui_filters_search_name (filter, name); - - if (item >= filter->allocated) - { - /* Increase number of filter entries */ - filter->items = realloc (filter->items, (filter->allocated + FILTER_ALLOC_NUMBER) * sizeof(ui_filter_item_t)); - filter->allocated += FILTER_ALLOC_NUMBER; - } - - if (value != FILTER_ID_UNDEFINED) - { - filter->items[item].id = value; - } - if (item >= filter->used) - { - /* New entry */ - strncpy (filter->items[item].name, name, SIGNAL_NAME_LENGTH); - ui_filter_set_enabled (&filter->items[item].enabled, entry_enabled, TRUE); - strncpy (filter->items[item].foreground, foreground != NULL ? foreground : COLOR_DARK_GREY, COLOR_SIZE); - strncpy (filter->items[item].background, background != NULL ? background : COLOR_WHITE, COLOR_SIZE); - - filter->used++; - } - else - { - ui_filter_set_enabled (&filter->items[item].enabled, entry_enabled, FALSE); - if (foreground != NULL) - { - strncpy (filter->items[item].foreground, foreground, COLOR_SIZE); - } - if (background != NULL) - { - strncpy (filter->items[item].background, background, COLOR_SIZE); - } - } - - g_debug("filter \"%s\" add %d \"%s\" %d", filter->name, value, name, entry_enabled); - - return (item); -} - -void ui_filters_add(ui_filter_e filter, uint32_t value, const char *name, ui_entry_enabled_e entry_enabled, - const char *foreground, const char *background) -{ - switch (filter) - { - case FILTER_MESSAGES: - ui_filter_add (&ui_filters.messages, value, name, entry_enabled, foreground, background); - break; - - case FILTER_ORIGIN_TASKS: - ui_filter_add (&ui_filters.origin_tasks, value, name, entry_enabled, foreground, background); - break; - - case FILTER_DESTINATION_TASKS: - ui_filter_add (&ui_filters.destination_tasks, value, name, entry_enabled, foreground, background); - break; - - case FILTER_INSTANCES: - ui_filter_add (&ui_filters.instances, value, name, entry_enabled, foreground, background); - break; - - default: - g_warning("unknown filter type %d", filter); - break; - } -} - -static gboolean ui_item_enabled(ui_filter_t *filter, const uint32_t value) -{ - int item; - - if (value != (uint32_t) ~0) - { - item = ui_filters_search_id (filter, value); - - if (item >= 0) - { - return (filter->items[item].enabled ? TRUE : FALSE); - } - } - return (FALSE); -} - -gboolean ui_filters_message_enabled(const uint32_t message, const uint32_t origin_task, const uint32_t destination_task, - const uint32_t instance) -{ - gboolean result; - - result = (ui_item_enabled (&ui_filters.messages, message) && ui_item_enabled (&ui_filters.origin_tasks, origin_task) - && ui_item_enabled (&ui_filters.destination_tasks, destination_task) - && ui_item_enabled (&ui_filters.instances, instance)); - - return result; -} - -static ui_filter_e ui_filter_from_name(const char *name) -{ - if (strcmp (name, ui_filters.messages.name) == 0) - { - return FILTER_MESSAGES; - } - if (strcmp (name, ui_filters.origin_tasks.name) == 0) - { - return FILTER_ORIGIN_TASKS; - } - if (strcmp (name, ui_filters.destination_tasks.name) == 0) - { - return FILTER_DESTINATION_TASKS; - } - if (strcmp (name, ui_filters.instances.name) == 0) - { - return FILTER_INSTANCES; - } - return FILTER_UNKNOWN; -} - -static int xml_parse_filters(xmlDocPtr doc, const char *file_name) -{ - xmlNode *root_element = NULL; - xmlNode *filter_node = NULL; - xmlNode *cur_node = NULL; - ui_filter_e filter; - guint filters_entries = 0; - int ret = RC_FAIL; - - /* Get the root element node */ - root_element = xmlDocGetRootElement (doc); - - if (root_element != NULL) - { - /* Search for the start of filters definition */ - for (cur_node = root_element; (cur_node != NULL) && (strcmp ((char *) cur_node->name, "filters") != 0); - cur_node = cur_node->next) - ; - - if (cur_node != NULL) - { - /* Search for filter header */ - for (filter_node = cur_node->children; filter_node != NULL;) - { - /* Search for next element node */ - for (; (filter_node != NULL) && (filter_node->type != XML_ELEMENT_NODE); filter_node = - filter_node->next) - ; - - if (filter_node != NULL) - { - filter = ui_filter_from_name ((const char*) filter_node->name); - g_debug("Found filter %s %d", filter_node->name, filter); - - if (filter == FILTER_UNKNOWN) - { - g_warning("Unknown filter \"%s\"", filter_node->name); - } - else - { - /* Search for entries */ - for (cur_node = filter_node->children; cur_node != NULL;) - { - /* Search for next element node */ - for (; (cur_node != NULL) && (cur_node->type != XML_ELEMENT_NODE); cur_node = - cur_node->next) - ; - - if (cur_node != NULL) - { - xmlAttr *prop_node; - ui_entry_enabled_e enabled = ENTRY_ENABLED_UNDEFINED; - char *foreground = NULL; - char *background = NULL; - - for (prop_node = cur_node->properties; prop_node != NULL; prop_node = prop_node->next) - { - if (strcmp ((char *) prop_node->name, ENABLED_NAME) == 0) - { - enabled = - prop_node->children->content[0] == '0' ? - ENTRY_ENABLED_FALSE : ENTRY_ENABLED_TRUE; - } - if (strcmp ((char *) prop_node->name, FOREGROUND_NAME) == 0) - { - foreground = (char *) prop_node->children->content; - } - if (strcmp ((char *) prop_node->name, BACKGROUND_NAME) == 0) - { - background = (char *) prop_node->children->content; - } - } - - g_debug(" Found entry %s %s", cur_node->name, cur_node->properties->children->content); - ui_filters_add (filter, FILTER_ID_UNDEFINED, (const char*) cur_node->name, enabled, - foreground, background); - - filters_entries++; - cur_node = cur_node->next; - } - } - } - filter_node = filter_node->next; - } - } - - /* Filters have changed destroy filter menus and update tree view */ - ui_destroy_filter_menus (); - - /* Reactivate filtering */ - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.filters_enabled), TRUE); - ui_tree_view_refilter (); - } - } - /* Free the document */ - xmlFreeDoc (doc); - - if (filters_entries > 0) - { - ret = RC_OK; - } - - g_message("Parsed XML filters file \"%s\", found %d entries (%d messages to display)", file_name, filters_entries, ui_tree_view_get_filtered_number()); - - return ret; -} - -int ui_filters_read(const char *file_name) -{ - xmlDocPtr doc; /* the resulting document tree */ - int ret; - - if (file_name == NULL) - { - g_warning("No name for filters file"); - return RC_FAIL; - } - - doc = xmlReadFile (file_name, NULL, 0); - if (doc == NULL) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open filters", "Failed to parse file \"%s\"", file_name); - return RC_FAIL; - } - - ret = xml_parse_filters (doc, file_name); - if (ret != RC_OK) - { - ui_notification_dialog (GTK_MESSAGE_WARNING, FALSE, "open filters", "Found no filter definitions in \"%s\"", - file_name); - return RC_FAIL; - } - - return ret; -} - -static void write_filter(FILE *filter_file, ui_filter_t *filter, gboolean save_colors) -{ - int item; - - fprintf (filter_file, " <%s>\n", filter->name); - for (item = 0; item < filter->used; item++) - { - if (save_colors) - { - fprintf (filter_file, - " <%s " ENABLED_NAME "=\"%d\" " FOREGROUND_NAME "=\"%s\" " BACKGROUND_NAME "=\"%s\"/>\n", - filter->items[item].name, filter->items[item].enabled ? 1 : 0, filter->items[item].foreground, - filter->items[item].background); - } - else - { - fprintf (filter_file, " <%s " ENABLED_NAME "=\"%d\"/>\n", filter->items[item].name, - filter->items[item].enabled ? 1 : 0); - } - } - fprintf (filter_file, " \n", filter->name); -} - -int ui_filters_file_write(const char *file_name) -{ - FILE *filter_file; - - if (file_name == NULL) - { - g_warning("No name for filters file"); - return RC_FAIL; - } - - filter_file = fopen (file_name, "w"); - if (filter_file == NULL) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Failed to open file \"%s\": %s", file_name, g_strerror (errno)); - return RC_FAIL; - } - - fprintf (filter_file, "\n" - "\n"); - - write_filter (filter_file, &ui_filters.messages, TRUE); - write_filter (filter_file, &ui_filters.origin_tasks, FALSE); - write_filter (filter_file, &ui_filters.destination_tasks, FALSE); - - fprintf (filter_file, "\n"); - - fclose (filter_file); - return RC_OK; -} - -static void ui_create_filter_menu(GtkWidget **menu, ui_filter_t *filter) -{ - if (*menu == NULL) - { - GtkWidget *menu_items; - int item; - gpointer data; - - *menu = gtk_menu_new (); - - /* Create the "NONE" menu-item */ - { - /* Create a new menu-item with a name */ - menu_items = gtk_menu_item_new_with_label ("NONE"); - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - - g_debug("ui_create_filter_menu %lx", (long) menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_none), *menu); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create the "ALL" menu-item */ - { - /* Create a new menu-item with a name */ - menu_items = gtk_menu_item_new_with_label ("ALL"); - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - - g_debug("ui_create_filter_menu %lx", (long) menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_all), *menu); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create separator */ - { - menu_items = gtk_menu_item_new (); - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Creates menu-items */ - for (item = 0; item < filter->used; item++) - { - /* Create a new menu-item with a name */ - menu_items = gtk_check_menu_item_new_with_label (filter->items[item].name); - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(menu_items), filter->items[item].enabled); - - /* Connect function to be called when the menu item is selected */ - data = &filter->items[item]; - g_debug("ui_create_filter_menu %lx %lx", (long) menu_items, (long) data); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_item_selected), data); - /* Save the menu_item reference */ - filter->items[item].menu_item = menu_items; - - /* Show the widget */ - gtk_widget_show (menu_items); - } - } -} - -void ui_create_filter_menus(void) -{ - ui_create_filter_menu (&ui_main_data.menu_filter_messages, &ui_filters.messages); - ui_create_filter_menu (&ui_main_data.menu_filter_origin_tasks, &ui_filters.origin_tasks); - ui_create_filter_menu (&ui_main_data.menu_filter_destination_tasks, &ui_filters.destination_tasks); - ui_create_filter_menu (&ui_main_data.menu_filter_instances, &ui_filters.instances); -} - -static void ui_destroy_filter_menu_item(GtkWidget *widget, gpointer data) -{ - if (GTK_IS_MENU_ITEM(widget)) - { - gtk_widget_destroy (widget); - } -} - -static void ui_destroy_filter_menu_widget(GtkWidget **menu) -{ - if (*menu != NULL) - { - gtk_container_foreach (GTK_CONTAINER(*menu), ui_destroy_filter_menu_item, NULL); - - gtk_widget_destroy (*menu); - *menu = NULL; - } -} - -void ui_destroy_filter_menus(void) -{ - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_messages); - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_origin_tasks); - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_destination_tasks); - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_instances); -} - -void ui_destroy_filter_menu(ui_filter_e filter) -{ - switch (filter) - { - case FILTER_MESSAGES: - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_messages); - break; - - case FILTER_ORIGIN_TASKS: - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_origin_tasks); - break; - - case FILTER_DESTINATION_TASKS: - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_destination_tasks); - break; - - case FILTER_INSTANCES: - ui_destroy_filter_menu_widget (&ui_main_data.menu_filter_instances); - break; - - default: - g_warning("unknown filter type %d", filter); - break; - } -} - -void ui_show_filter_menu(GtkWidget **menu, ui_filter_t *filter) -{ - ui_create_filter_menu (menu, filter); - - gtk_menu_popup (GTK_MENU (*menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); -} diff --git a/common/utils/itti_analyzer/libui/ui_filters.h b/common/utils/itti_analyzer/libui/ui_filters.h deleted file mode 100644 index 16bb38834b..0000000000 --- a/common/utils/itti_analyzer/libui/ui_filters.h +++ /dev/null @@ -1,95 +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 - */ - -#ifndef UI_FILTERS_H_ -#define UI_FILTERS_H_ - -#include - -#include "itti_types.h" - -#define SIGNAL_NAME_LENGTH 100 -#define COLOR_SIZE 10 - -typedef enum -{ - FILTER_UNKNOWN, FILTER_MESSAGES, FILTER_ORIGIN_TASKS, FILTER_DESTINATION_TASKS, FILTER_INSTANCES, -} ui_filter_e; - -typedef enum -{ - ENTRY_ENABLED_FALSE, ENTRY_ENABLED_TRUE, ENTRY_ENABLED_UNDEFINED, -} ui_entry_enabled_e; - -typedef struct -{ - uint32_t id; - char name[SIGNAL_NAME_LENGTH]; - uint8_t enabled; - char foreground[COLOR_SIZE]; - char background[COLOR_SIZE]; - GtkWidget *menu_item; -} ui_filter_item_t; - -typedef struct -{ - char *name; - uint32_t allocated; - uint32_t used; - ui_filter_item_t *items; -} ui_filter_t; - -typedef struct -{ - gboolean filters_enabled; - ui_filter_t messages; - ui_filter_t origin_tasks; - ui_filter_t destination_tasks; - ui_filter_t instances; -} ui_filters_t; - -extern ui_filters_t ui_filters; - -int ui_init_filters(int reset, int clear_ids); - -gboolean ui_filters_enable(gboolean enabled); - -int ui_filters_search_id(ui_filter_t *filter, uint32_t value); - -void ui_filters_add(ui_filter_e filter, uint32_t value, const char *name, ui_entry_enabled_e entry_enabled, - const char *foreground, const char *background); - -gboolean ui_filters_message_enabled(const uint32_t message, const uint32_t origin_task, const uint32_t destination_task, - const uint32_t instance); - -int ui_filters_read(const char *file_name); - -int ui_filters_file_write(const char *file_name); - -void ui_create_filter_menus(void); - -void ui_destroy_filter_menus(void); - -void ui_destroy_filter_menu(ui_filter_e filter); - -void ui_show_filter_menu(GtkWidget **menu, ui_filter_t *filter); - -#endif /* UI_FILTERS_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_interface.c b/common/utils/itti_analyzer/libui/ui_interface.c deleted file mode 100644 index 56139a8c6b..0000000000 --- a/common/utils/itti_analyzer/libui/ui_interface.c +++ /dev/null @@ -1,122 +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 - */ - -#include -#include -#include - -#define G_LOG_DOMAIN ("UI_INTER") - -#include - -#include "ui_interface.h" - -#include "ui_tree_view.h" -#include "ui_notifications.h" -#include "ui_signal_dissect_view.h" - -#include "socket.h" -#include "xml_parse.h" - -static -gboolean ui_callback_on_pipe_notification( - GIOChannel *source, GIOCondition condition, gpointer user_data) -{ - pipe_input_t *pipe_input = (pipe_input_t *)user_data; - - /* avoid reentrancy problems and stack overflow */ - g_source_remove(pipe_input->pipe_input_id); - - g_debug("Received new data on pipe %d", pipe_input->pipe_input_id); - - if (pipe_input->input_cb(pipe_input->source_fd, pipe_input->user_data)) { - /* restore pipe handler */ - pipe_input->pipe_input_id = g_io_add_watch_full(pipe_input->pipe_channel, - G_PRIORITY_HIGH, - (GIOCondition)(G_IO_IN|G_IO_ERR|G_IO_HUP), - ui_callback_on_pipe_notification, - pipe_input, - NULL); - } - return TRUE; -} - -int ui_pipe_new(int pipe_fd[2], pipe_input_cb_t input_cb, gpointer user_data) -{ - static pipe_input_t pipe_input; - - g_assert(pipe_fd != NULL); - - /* Create a pipe between GUI and a thread or a process */ - if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pipe_fd) < 0) { - g_warning("Failed to create socketpair %s", g_strerror(errno)); - return RC_FAIL; - } - - /* Source taken from wireshark SVN repository */ - - pipe_input.source_fd = pipe_fd[0]; - pipe_input.input_cb = input_cb; - pipe_input.user_data = user_data; - - pipe_input.pipe_channel = g_io_channel_unix_new(pipe_fd[0]); - g_io_channel_set_encoding(pipe_input.pipe_channel, NULL, NULL); - pipe_input.pipe_input_id = g_io_add_watch_full(pipe_input.pipe_channel, - G_PRIORITY_HIGH, - G_IO_IN | G_IO_ERR | G_IO_HUP, - ui_callback_on_pipe_notification, - &pipe_input, - NULL); - - return RC_OK; -} - -int ui_pipe_write_message(int pipe_fd, const uint16_t message_type, - const void * const message, const uint16_t message_size) -{ - int ret; - pipe_input_header_t pipe_input_header; - - pipe_input_header.message_size = message_size + sizeof(pipe_input_header); - pipe_input_header.message_type = message_type; - - if (message_size > 0 && message == NULL) { - g_error("message size = %u but message is NULL", message_size); - g_assert_not_reached(); - } - - ret = write(pipe_fd, &pipe_input_header, sizeof(pipe_input_header)); - if (ret < 0) { - g_warning("Failed to write header to pipe: %s", g_strerror(errno)); - return ret; - } - - /* Only write the message to pipe if valid data to transmit */ - if (message_size > 0) { - ret = write(pipe_fd, message, message_size); - if (ret < 0) { - g_warning("Failed to write message of size %u at 0x%p to pipe: %s", - message_size, message, g_strerror(errno)); - return ret; - } - } - return 0; -} diff --git a/common/utils/itti_analyzer/libui/ui_interface.h b/common/utils/itti_analyzer/libui/ui_interface.h deleted file mode 100644 index f77ec144d1..0000000000 --- a/common/utils/itti_analyzer/libui/ui_interface.h +++ /dev/null @@ -1,78 +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 - */ - -#include - -#ifndef UI_INTERFACE_H_ -#define UI_INTERFACE_H_ - -/******************************************************************************* - * Functions used between dissectors and GUI to update signal dissection - ******************************************************************************/ - -typedef gboolean (*ui_set_signal_text_cb_t) (gpointer user_data, gchar *text, gint length); - -/******************************************************************************* - * Pipe interface between GUI thread and other thread - ******************************************************************************/ - -typedef gboolean (*pipe_input_cb_t) (gint source, gpointer user_data); - -typedef struct { - int source_fd; - guint pipe_input_id; - GIOChannel *pipe_channel; - - pipe_input_cb_t input_cb; - gpointer user_data; -} pipe_input_t; - -int ui_pipe_new(int pipe_fd[2], pipe_input_cb_t input_cb, gpointer user_data); - -int ui_pipe_write_message(int pipe_fd, const uint16_t message_type, - const void * const message, const uint16_t message_size); - -typedef struct { - uint16_t message_size; - uint16_t message_type; -} pipe_input_header_t; - -enum ui_pipe_messages_id_e { - /* Other thread -> GUI interface ids */ - UI_PIPE_CONNECTION_FAILED, - UI_PIPE_CONNECTION_LOST, - UI_PIPE_XML_DEFINITION, - UI_PIPE_UPDATE_SIGNAL_LIST, - - /* GUI -> other threads */ - UI_PIPE_DISCONNECT_EVT -}; - -typedef struct { - char *xml_definition; - size_t xml_definition_length; -} pipe_xml_definition_message_t; - -typedef struct { - GList *signal_list; -} pipe_new_signals_list_message_t; - -#endif /* UI_INTERFACE_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_main_screen.c b/common/utils/itti_analyzer/libui/ui_main_screen.c deleted file mode 100644 index 3d6ea266be..0000000000 --- a/common/utils/itti_analyzer/libui/ui_main_screen.c +++ /dev/null @@ -1,238 +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 - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("UI") - -#include - -#include "logs.h" -#include "rc.h" - -#include "ui_callbacks.h" -#include "ui_interface.h" -#include "ui_main_screen.h" -#include "ui_menu_bar.h" -#include "ui_tree_view.h" -#include "ui_notebook.h" -#include "ui_notifications.h" -#include "ui_filters.h" - -ui_main_data_t ui_main_data; - -static void ui_help(void) -{ - printf ("Usage: itti_analyser [options]\n\n" - "Options:\n" - " -d DISSECT write DISSECT file with message types parse details\n" - " -f FILTERS read filters from FILTERS file\n" - " -h display this help and exit\n" - " -i IP set ip address to IP\n" - " -l LEVEL set log level to LEVEL in the range of 2 to 7\n" - " -m MESSAGES read messages from MESSAGES file\n" - " -p PORT set port to PORT\n"); -} - -void ui_gtk_parse_arg(int argc, char *argv[]) -{ - char c; - - /* Clear of ui_main_data not needed */ - // memset (&ui_main_data, 0, sizeof(ui_main_data_t)); - - /* Set some default initialization value for the IP address */ - ui_main_data.ip_entry_init = "127.0.0.1"; - ui_main_data.port_entry_init = "10006"; - - /* Set default log level to at least warning level messages */ - ui_main_data.log_flags = (G_LOG_LEVEL_MASK & (~(G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG))); - - while ((c = getopt (argc, argv, "d:f:hi:l:m:p:")) != -1) - { - switch (c) - { - case 'd': - ui_main_data.dissect_file_name = malloc (strlen (optarg) + 1); - if (ui_main_data.dissect_file_name != NULL) - { - strcpy (ui_main_data.dissect_file_name, optarg); - } - break; - - case 'f': - ui_main_data.filters_file_name = malloc (strlen (optarg) + 1); - if (ui_main_data.filters_file_name != NULL) - { - strcpy (ui_main_data.filters_file_name, optarg); - } - break; - - case 'h': - ui_help (); - exit (0); - break; - - case 'i': - ui_main_data.ip_entry_init = optarg; - break; - - case 'l': - { - GLogLevelFlags log_flag; - - log_flag = 1 << atoi(optarg); - if (log_flag < G_LOG_LEVEL_ERROR) - { - log_flag = G_LOG_LEVEL_ERROR; - } - else - { - if (log_flag > G_LOG_LEVEL_DEBUG) - { - log_flag = G_LOG_LEVEL_DEBUG; - } - } - ui_main_data.log_flags = ((log_flag << 1) - 1) & G_LOG_LEVEL_MASK; - break; - } - - case 'm': - ui_main_data.messages_file_name = malloc (strlen (optarg) + 1); - if (ui_main_data.messages_file_name != NULL) - { - strcpy (ui_main_data.messages_file_name, optarg); - } - break; - - case 'p': - ui_main_data.port_entry_init = optarg; - break; - - default: - ui_help (); - exit (-1); - break; - } - } -} - -static int ui_idle_callback(gpointer data) -{ - g_info("Entering idle state"); - - gtk_window_set_focus (GTK_WINDOW(ui_main_data.window), ui_main_data.messages_list); - - /* Read filters file */ - if (ui_main_data.filters_file_name != NULL) - { - ui_filters_read(ui_main_data.filters_file_name); - } - - /* Read messages file */ - if (ui_main_data.messages_file_name != NULL) - { - ui_messages_read (ui_main_data.messages_file_name); - } - - /* One shot execution */ - return FALSE; -} - -void ui_set_title(const char *fmt, ...) -{ - va_list args; - char *name; - char buffer[200]; - char title[220]; - -#if defined(PACKAGE_STRING) - name = PACKAGE_NAME; -#else - name = "itti_analyzer"; -#endif - - va_start(args, fmt); - - vsnprintf (buffer, sizeof(buffer), fmt, args); - snprintf (title, sizeof(title), "%s %s", name, buffer); - va_end (args); - - gtk_window_set_title (GTK_WINDOW(ui_main_data.window), title); -} - -void ui_main_window_destroy (void) -{ - ui_callback_dialogbox_connect_destroy(); - ui_progressbar_window_destroy(); - gtk_main_quit(); -} - -int ui_gtk_initialize(int argc, char *argv[]) -{ - GtkWidget *vbox; - - /* Create the main window */ - ui_main_data.window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - ui_init_filters (TRUE, FALSE); - - // gtk_window_set_default_icon_from_file ("../analyzer.png", NULL); - gtk_window_set_default_icon_name (GTK_STOCK_FIND); - - gtk_window_set_position (GTK_WINDOW(ui_main_data.window), GTK_WIN_POS_CENTER); - gtk_window_set_default_size (GTK_WINDOW(ui_main_data.window), 1024, 800); - ui_set_title(""); - gtk_window_set_resizable (GTK_WINDOW(ui_main_data.window), TRUE); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - - CHECK_FCT(ui_menu_bar_create(vbox)); - CHECK_FCT(ui_toolbar_create(vbox)); - CHECK_FCT(ui_notebook_create(vbox)); - - gtk_container_add (GTK_CONTAINER(ui_main_data.window), vbox); - - /* Assign the destroy event */ - g_signal_connect(ui_main_data.window, "destroy", ui_main_window_destroy, NULL); - - /* Show the application window */ - gtk_widget_show_all (ui_main_data.window); - - g_idle_add (ui_idle_callback, NULL); - - return RC_OK; -} - -void ui_gtk_flush_events(void) -{ - while (gtk_events_pending ()) - { - gtk_main_iteration(); - } -} diff --git a/common/utils/itti_analyzer/libui/ui_main_screen.h b/common/utils/itti_analyzer/libui/ui_main_screen.h deleted file mode 100644 index 0411d687be..0000000000 --- a/common/utils/itti_analyzer/libui/ui_main_screen.h +++ /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 - */ - -#ifndef UI_MAIN_SCREEN_H_ -#define UI_MAIN_SCREEN_H_ - -#include - -#include "ui_signal_dissect_view.h" - -typedef struct { - GtkWidget *window; - GtkWidget *ip_entry; - char *ip_entry_init; - GtkWidget *port_entry; - char *port_entry_init; - - GtkWidget *progressbar_window; - GtkWidget *progressbar; - GtkWidget *messages_list; - ui_text_view_t *text_view; - - /* Buttons */ - GtkToolItem *filters_enabled; - GtkToolItem *open_filters_file; - GtkToolItem *refresh_filters_file; - GtkToolItem *save_filters_file; - - GtkToolItem *open_replay_file; - GtkToolItem *refresh_replay_file; - GtkToolItem *stop_loading; - GtkToolItem *save_replay_file; - GtkToolItem *save_replay_file_filtered; - - GtkToolItem *auto_reconnect; - GtkToolItem *connect; - GtkToolItem *disconnect; - - /* Signal list buttons */ - /* Clear signals button */ - GtkWidget *signals_go_to_entry; - GtkToolItem *signals_go_to_last_button; - GtkToolItem *signals_go_to_first_button; - gboolean display_message_header; - gboolean display_brace; - - GtkTreeSelection *selection; - gboolean follow_last; - - /* Nb of messages received */ - guint nb_message_received; - - GLogLevelFlags log_flags; - char *dissect_file_name; - char *filters_file_name; - char *messages_file_name; - - GtkWidget *menu_filter_messages; - GtkWidget *menu_filter_origin_tasks; - GtkWidget *menu_filter_destination_tasks; - GtkWidget *menu_filter_instances; - - int pipe_fd[2]; -} ui_main_data_t; - -extern ui_main_data_t ui_main_data; - -void ui_gtk_parse_arg(int argc, char *argv[]); - -void ui_set_title(const char *fmt, ...); - -void ui_main_window_destroy (void); - -int ui_gtk_initialize(int argc, char *argv[]); - -void ui_gtk_flush_events(void); - -#endif /* UI_MAIN_SCREEN_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_menu_bar.c b/common/utils/itti_analyzer/libui/ui_menu_bar.c deleted file mode 100644 index 62b51b3b9f..0000000000 --- a/common/utils/itti_analyzer/libui/ui_menu_bar.c +++ /dev/null @@ -1,503 +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 - */ - -#define G_LOG_DOMAIN ("UI") - -#include -#include - -#include "rc.h" -#include "ui_main_screen.h" -#include "ui_menu_bar.h" -#include "ui_callbacks.h" -#include "ui_notifications.h" - -static const guint BUTTON_SPACE = 0; -static const guint LABEL_SPACE = 5; -static const guint SEPARATOR_SPACE = 5; - -void ui_set_sensitive_move_buttons(gboolean enable) -{ - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_last_button), enable); - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_first_button), enable); -} - -void ui_set_sensitive_save_message_buttons(gboolean enable) -{ - if (ui_main_data.nb_message_received == 0) - { - enable = FALSE; - } - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.save_replay_file), enable); - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.save_replay_file_filtered), enable); -} - -int ui_menu_bar_create(GtkWidget *vbox) -{ - GtkAccelGroup *accel_group; - GtkWidget *menu_bar; - - GtkWidget *system_menu; - GtkWidget *system; - GtkWidget *quit; - - GtkWidget *filters_menu; - GtkWidget *filters; - GtkWidget *open_filters; - GtkWidget *reload_filters; - GtkWidget *save_filters; - GtkWidget *enable_filters; - - GtkWidget *messages_menu; - GtkWidget *messages; - GtkWidget *open_messages; - GtkWidget *reload_messages; - GtkWidget *stop_loading; - GtkWidget *save_messages; - GtkWidget *save_messages_filtered; - GtkWidget *goto_first_messages; - GtkWidget *goto_messages; - GtkWidget *goto_last_messages; - GtkWidget *display_message_header; - GtkWidget *display_brace; - - GtkWidget *connect_menu; - GtkWidget *connect; - GtkWidget *auto_reconnect; - GtkWidget *connect_to; - GtkWidget *disconnect; - - GtkWidget *help_menu; - GtkWidget *help; - GtkWidget *about; - - if (!vbox) - return RC_BAD_PARAM; - - accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group(GTK_WINDOW(ui_main_data.window), accel_group); - - menu_bar = gtk_menu_bar_new(); - - /* Create the System sub-menu */ - { - system = gtk_menu_item_new_with_mnemonic ("_System"); - gtk_menu_shell_append (GTK_MENU_SHELL(menu_bar), system); - - system_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM(system), system_menu); - - /* Create the Filters menu items */ - { - quit = gtk_menu_item_new_with_mnemonic ("_Quit"); - gtk_widget_add_accelerator (quit, "activate", accel_group, GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(system_menu), quit); - g_signal_connect(G_OBJECT(quit), "activate", ui_main_window_destroy, NULL); - } - } - - /* Create the Filters sub-menu */ - { - filters = gtk_menu_item_new_with_mnemonic ("_Filters"); - gtk_menu_shell_append (GTK_MENU_SHELL(menu_bar), filters); - - filters_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM(filters), filters_menu); - - /* Create the Filters menu items */ - { - open_filters = gtk_menu_item_new_with_mnemonic ("_Open filters file"); - gtk_widget_add_accelerator (open_filters, "activate", accel_group, GDK_KEY_p, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(filters_menu), open_filters); - g_signal_connect(G_OBJECT(open_filters), "activate", G_CALLBACK(ui_callback_on_open_filters), (gpointer) FALSE); - - reload_filters = gtk_menu_item_new_with_mnemonic ("_Reload filters file"); - gtk_widget_add_accelerator (reload_filters, "activate", accel_group, GDK_KEY_d, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_widget_add_accelerator (reload_filters, "activate", accel_group, GDK_KEY_F4, 0, GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(filters_menu), reload_filters); - g_signal_connect(G_OBJECT(reload_filters), "activate", G_CALLBACK(ui_callback_on_open_filters), - (gpointer) TRUE); - - save_filters = gtk_menu_item_new_with_mnemonic ("_Save filters file"); - gtk_widget_add_accelerator (save_filters, "activate", accel_group, GDK_KEY_v, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(filters_menu), save_filters); - g_signal_connect(G_OBJECT(save_filters), "activate", G_CALLBACK(ui_callback_on_save_filters), NULL); - - gtk_menu_shell_append (GTK_MENU_SHELL(filters_menu), gtk_menu_item_new ()); // Separator - - enable_filters = gtk_menu_item_new_with_mnemonic ("_Enable filtering"); - gtk_widget_add_accelerator (enable_filters, "activate", accel_group, GDK_KEY_e, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(filters_menu), enable_filters); - g_signal_connect(G_OBJECT(enable_filters), "activate", G_CALLBACK(ui_callback_on_enable_filters), NULL); - } - } - - /* Create the Messages sub-menu */ - { - messages = gtk_menu_item_new_with_mnemonic ("_Messages"); - gtk_menu_shell_append (GTK_MENU_SHELL(menu_bar), messages); - - messages_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM(messages), messages_menu); - - /* Crate the Messages menu items */ - { - open_messages = gtk_menu_item_new_with_mnemonic ("_Open messages file"); - gtk_widget_add_accelerator (open_messages, "activate", accel_group, GDK_KEY_o, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), open_messages); - g_signal_connect(G_OBJECT(open_messages), "activate", G_CALLBACK(ui_callback_on_open_messages), - (gpointer) FALSE); - - reload_messages = gtk_menu_item_new_with_mnemonic ("_Reload messages file"); - gtk_widget_add_accelerator (reload_messages, "activate", accel_group, GDK_KEY_r, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_widget_add_accelerator (reload_messages, "activate", accel_group, GDK_KEY_F5, 0, GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), reload_messages); - g_signal_connect(G_OBJECT(reload_messages), "activate", G_CALLBACK(ui_callback_on_open_messages), - (gpointer) TRUE); - - stop_loading = gtk_menu_item_new_with_mnemonic ("S_top loading messages file"); - gtk_widget_add_accelerator (stop_loading, "activate", accel_group, GDK_KEY_x, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), stop_loading); - g_signal_connect(G_OBJECT(stop_loading), "activate", G_CALLBACK(ui_progressbar_window_destroy), - NULL); - - save_messages = gtk_menu_item_new_with_mnemonic ("S_ave messages file (all)"); - gtk_widget_add_accelerator (save_messages, "activate", accel_group, GDK_KEY_a, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), save_messages); - g_signal_connect(G_OBJECT(save_messages), "activate", G_CALLBACK(ui_callback_on_save_messages), - (gpointer) FALSE); - - save_messages_filtered = gtk_menu_item_new_with_mnemonic ("_Save messages file (filtered)"); - gtk_widget_add_accelerator (save_messages_filtered, "activate", accel_group, GDK_KEY_s, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), save_messages_filtered); - g_signal_connect(G_OBJECT(save_messages_filtered), "activate", G_CALLBACK(ui_callback_on_save_messages), - (gpointer) TRUE); - - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), gtk_menu_item_new ()); // Separator - - goto_first_messages = gtk_menu_item_new_with_mnemonic ("Go to _first message"); - gtk_widget_add_accelerator (goto_first_messages, "activate", accel_group, GDK_KEY_f, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), goto_first_messages); - g_signal_connect(G_OBJECT(goto_first_messages), "activate", G_CALLBACK(ui_callback_signal_go_to_first), - NULL); - - goto_messages = gtk_menu_item_new_with_mnemonic ("_Go to message ..."); - gtk_widget_add_accelerator (goto_messages, "activate", accel_group, GDK_KEY_g, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), goto_messages); - g_signal_connect(G_OBJECT(goto_messages), "activate", G_CALLBACK(ui_callback_signal_go_to), NULL); - - goto_last_messages = gtk_menu_item_new_with_mnemonic ("Go to _last message"); - gtk_widget_add_accelerator (goto_last_messages, "activate", accel_group, GDK_KEY_l, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), goto_last_messages); - g_signal_connect(G_OBJECT(goto_last_messages), "activate", G_CALLBACK(ui_callback_signal_go_to_last), (gpointer) TRUE); - - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), gtk_menu_item_new ()); // Separator - - display_message_header = gtk_menu_item_new_with_mnemonic ("Display message _header"); - gtk_widget_add_accelerator (display_message_header, "activate", accel_group, GDK_KEY_h, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), display_message_header); - g_signal_connect(G_OBJECT(display_message_header), "activate", - G_CALLBACK(ui_callback_display_message_header), NULL); - - display_brace = gtk_menu_item_new_with_mnemonic ("Display _brace"); - gtk_widget_add_accelerator (display_brace, "activate", accel_group, GDK_KEY_b, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(messages_menu), display_brace); - g_signal_connect(G_OBJECT(display_brace), "activate", G_CALLBACK(ui_callback_display_brace), NULL); - } - } - - /* Create the Connect sub-menu */ - { - connect = gtk_menu_item_new_with_mnemonic ("_Connect"); - gtk_menu_shell_append (GTK_MENU_SHELL(menu_bar), connect); - - connect_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM(connect), connect_menu); - - /* Create the Help menu item */ - { - auto_reconnect = gtk_menu_item_new_with_mnemonic ("_Automatic reconnection"); - gtk_widget_add_accelerator (auto_reconnect, "activate", accel_group, GDK_KEY_t, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(connect_menu), auto_reconnect); - g_signal_connect(G_OBJECT(auto_reconnect), "activate", G_CALLBACK(ui_callback_on_auto_reconnect), (gpointer) TRUE); - - connect_to = gtk_menu_item_new_with_mnemonic ("_Connect"); - gtk_widget_add_accelerator (connect_to, "activate", accel_group, GDK_KEY_c, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(connect_menu), connect_to); - g_signal_connect(G_OBJECT(connect_to), "activate", G_CALLBACK(ui_callback_on_connect), (gpointer) TRUE); - - disconnect = gtk_menu_item_new_with_mnemonic ("_Disconnect"); - gtk_widget_add_accelerator (disconnect, "activate", accel_group, GDK_KEY_u, GDK_CONTROL_MASK, - GTK_ACCEL_VISIBLE); - gtk_menu_shell_append (GTK_MENU_SHELL(connect_menu), disconnect); - g_signal_connect(G_OBJECT(disconnect), "activate", G_CALLBACK(ui_callback_on_disconnect), NULL); - } - } - - /* Create the Help sub-menu */ - { - help = gtk_menu_item_new_with_mnemonic ("_Help"); - gtk_menu_shell_append (GTK_MENU_SHELL(menu_bar), help); - - help_menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM(help), help_menu); - - /* Create the Help menu item */ - { - about = gtk_menu_item_new_with_mnemonic ("_About"); - gtk_menu_shell_append (GTK_MENU_SHELL(help_menu), about); - g_signal_connect(G_OBJECT(about), "activate", G_CALLBACK(ui_callback_on_about), NULL); - } - } - - /* Add the menubar to the vbox */ - gtk_box_pack_start(GTK_BOX(vbox), menu_bar, FALSE, FALSE, 3); - - return RC_OK; -} - -int ui_toolbar_create(GtkWidget *vbox) -{ - GtkWidget *hbox; - GtkWidget *messages_label; - GtkWidget *ip_label; - GtkWidget *port_label; - - if (!vbox) - return RC_BAD_PARAM; - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - - messages_label = gtk_label_new("Messages"); - - /* Button to Enable filtering */ - { - ui_main_data.filters_enabled = gtk_toggle_tool_button_new(); - gtk_tool_button_set_label (GTK_TOOL_BUTTON(ui_main_data.filters_enabled), "Filters"); - g_signal_connect(G_OBJECT(ui_main_data.filters_enabled), "clicked", - G_CALLBACK(ui_callback_on_filters_enabled), NULL); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.filters_enabled), TRUE); - } - - /* Button to open filters file */ - { - ui_main_data.open_filters_file = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.open_filters_file), "Open filters file"); - - g_signal_connect(G_OBJECT(ui_main_data.open_filters_file), "clicked", - G_CALLBACK(ui_callback_on_open_filters), (gpointer) FALSE); - } - - /* Button to refresh filters file */ - { - ui_main_data.refresh_filters_file = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.refresh_filters_file), "Reload filters file"); - - g_signal_connect(G_OBJECT(ui_main_data.refresh_filters_file), "clicked", - G_CALLBACK(ui_callback_on_open_filters), (gpointer) TRUE); - } - - /* Button to save filters file */ - { - ui_main_data.save_filters_file = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.save_filters_file), "Save filters file"); - - g_signal_connect(G_OBJECT(ui_main_data.save_filters_file), "clicked", - G_CALLBACK(ui_callback_on_save_filters), NULL); - } - - /* Button to open messages file */ - { - ui_main_data.open_replay_file = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.open_replay_file), "Open messages file"); - - g_signal_connect(G_OBJECT(ui_main_data.open_replay_file), "clicked", - G_CALLBACK(ui_callback_on_open_messages), (gpointer) FALSE); - } - - /* Button to refresh messages file */ - { - ui_main_data.refresh_replay_file = gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.refresh_replay_file), "Reload messages file"); - - g_signal_connect(G_OBJECT(ui_main_data.refresh_replay_file), "clicked", - G_CALLBACK(ui_callback_on_open_messages), (gpointer) TRUE); - } - - /* Stop reading messages file */ - { - ui_main_data.stop_loading = gtk_tool_button_new_from_stock(GTK_STOCK_STOP); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.stop_loading), "Stop loading messages file"); - - g_signal_connect(G_OBJECT(ui_main_data.stop_loading), "clicked", - ui_progressbar_window_destroy, NULL); - } - - /* Button to save messages file */ - { - ui_main_data.save_replay_file = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.save_replay_file), "Save messages file (all)"); - - g_signal_connect(G_OBJECT(ui_main_data.save_replay_file), "clicked", - G_CALLBACK(ui_callback_on_save_messages), (gpointer) FALSE); - } - - /* Button to save messages file */ - { - ui_main_data.save_replay_file_filtered = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE_AS); - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.save_replay_file_filtered), "Save messages file (filtered)"); - - g_signal_connect(G_OBJECT(ui_main_data.save_replay_file_filtered), "clicked", - G_CALLBACK(ui_callback_on_save_messages), (gpointer) TRUE); - } - - /* Button to go to first signal in list */ - { - ui_main_data.signals_go_to_first_button = gtk_tool_button_new_from_stock(GTK_STOCK_GOTO_FIRST); - /* Set the tooltip text */ - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.signals_go_to_first_button), "Goto first signal"); - - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_first_button), FALSE); - - g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_first_button), "clicked", - G_CALLBACK(ui_callback_signal_go_to_first), NULL); - } - - /* Entry to go to given signal number */ - { - ui_main_data.signals_go_to_entry = gtk_entry_new (); - gtk_entry_set_width_chars (GTK_ENTRY(ui_main_data.signals_go_to_entry), 10); - // gtk_entry_set_input_purpose (GTK_ENTRY(ui_main_data.signals_go_to_entry), GTK_INPUT_PURPOSE_DIGITS); - - g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_entry), "activate", - G_CALLBACK(ui_callback_signal_go_to_entry), NULL); - } - - /* Button to go to last signal in list */ - { - ui_main_data.signals_go_to_last_button = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_GOTO_LAST); - /* Set the tooltip text */ - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.signals_go_to_last_button), "Goto last signal"); - - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.signals_go_to_last_button), FALSE); - - g_signal_connect(G_OBJECT(ui_main_data.signals_go_to_last_button), "clicked", - G_CALLBACK(ui_callback_signal_go_to_last), (gpointer) FALSE); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.signals_go_to_last_button), TRUE); - } - - /* Button to automatically try to reconnect */ - { - ui_main_data.auto_reconnect = gtk_toggle_tool_button_new(); - gtk_tool_button_set_label (GTK_TOOL_BUTTON(ui_main_data.auto_reconnect), "Auto"); - g_signal_connect(G_OBJECT(ui_main_data.auto_reconnect), "clicked", - G_CALLBACK(ui_callback_on_auto_reconnect), (gpointer) FALSE); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(ui_main_data.auto_reconnect), FALSE); - } - - /* Button to connect to remote */ - { - ui_main_data.connect = gtk_tool_button_new_from_stock(GTK_STOCK_CONNECT); - /* Set the tooltip text */ - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.connect), "Connect to remote host"); - - g_signal_connect(G_OBJECT(ui_main_data.connect), "clicked", - G_CALLBACK(ui_callback_on_connect), (gpointer) TRUE); - } - - /* Button to disconnect from remote */ - { - ui_main_data.disconnect = gtk_tool_button_new_from_stock(GTK_STOCK_DISCONNECT); - /* Set the tooltip text */ - gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(ui_main_data.disconnect), "Disconnect from remote host"); - - /* Disabled at startup. Will be activated when a connection is established */ - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.disconnect), FALSE); - - g_signal_connect(G_OBJECT(ui_main_data.disconnect), "clicked", - G_CALLBACK(ui_callback_on_disconnect), NULL); - } - - ip_label = gtk_label_new("ip:"); - port_label = gtk_label_new("port:"); - - ui_main_data.ip_entry = gtk_entry_new(); - /* Width of 15 characters for port number (ipv4 address) */ - gtk_entry_set_width_chars(GTK_ENTRY(ui_main_data.ip_entry), 15); - gtk_entry_set_text(GTK_ENTRY(ui_main_data.ip_entry), ui_main_data.ip_entry_init); - - ui_main_data.port_entry = gtk_entry_new(); - /* Width of 5 characters for port number (uint16_t) */ - gtk_entry_set_width_chars(GTK_ENTRY(ui_main_data.port_entry), 5); - gtk_entry_set_text(GTK_ENTRY(ui_main_data.port_entry), ui_main_data.port_entry_init); - - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.filters_enabled), FALSE, FALSE, LABEL_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.open_filters_file), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.refresh_filters_file), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.save_filters_file), FALSE, FALSE, BUTTON_SPACE); - - gtk_box_pack_start(GTK_BOX(hbox), gtk_separator_new(GTK_ORIENTATION_VERTICAL), FALSE, FALSE, SEPARATOR_SPACE); - - gtk_box_pack_start(GTK_BOX(hbox), messages_label, FALSE, FALSE, LABEL_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.open_replay_file), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.refresh_replay_file), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.stop_loading), FALSE, FALSE, BUTTON_SPACE); - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.stop_loading), FALSE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.save_replay_file), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.save_replay_file_filtered), FALSE, FALSE, BUTTON_SPACE); - ui_set_sensitive_save_message_buttons(FALSE); - - gtk_box_pack_start(GTK_BOX(hbox), gtk_separator_new(GTK_ORIENTATION_VERTICAL), FALSE, FALSE, SEPARATOR_SPACE); - - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.signals_go_to_first_button), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.signals_go_to_entry), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.signals_go_to_last_button), FALSE, FALSE, BUTTON_SPACE); - - gtk_box_pack_start(GTK_BOX(hbox), gtk_separator_new(GTK_ORIENTATION_VERTICAL), FALSE, FALSE, SEPARATOR_SPACE); - - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.auto_reconnect), FALSE, FALSE, LABEL_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.connect), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(ui_main_data.disconnect), FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), ip_label, FALSE, FALSE, LABEL_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), ui_main_data.ip_entry, FALSE, FALSE, BUTTON_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), port_label, FALSE, FALSE, LABEL_SPACE); - gtk_box_pack_start(GTK_BOX(hbox), ui_main_data.port_entry, FALSE, FALSE, BUTTON_SPACE); - - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); - - return RC_OK; -} diff --git a/common/utils/itti_analyzer/libui/ui_menu_bar.h b/common/utils/itti_analyzer/libui/ui_menu_bar.h deleted file mode 100644 index 037dc5edca..0000000000 --- a/common/utils/itti_analyzer/libui/ui_menu_bar.h +++ /dev/null @@ -1,33 +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 - */ - -#ifndef UI_MENU_BAR_H_ -#define UI_MENU_BAR_H_ - -void ui_set_sensitive_move_buttons(gboolean enable); - -void ui_set_sensitive_save_message_buttons(gboolean enable); - -int ui_menu_bar_create(GtkWidget *vbox); - -int ui_toolbar_create(GtkWidget *vbox); - -#endif /* UI_MENU_BAR_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_notebook.c b/common/utils/itti_analyzer/libui/ui_notebook.c deleted file mode 100644 index 93a439335f..0000000000 --- a/common/utils/itti_analyzer/libui/ui_notebook.c +++ /dev/null @@ -1,88 +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 - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#define G_LOG_DOMAIN ("UI") - -#include - -#include "rc.h" - -#include "ui_notebook.h" -#include "ui_tree_view.h" -#include "ui_signal_dissect_view.h" - -static ui_text_view_t *terminal_view; - -void ui_notebook_terminal_clear(void) -{ - ui_signal_dissect_clear_view(terminal_view); -} - -void ui_notebook_terminal_append_data(gchar *text, gint length) -{ - ui_signal_set_text(terminal_view, text, length); -} - -int ui_notebook_create(GtkWidget *vbox) -{ - GtkWidget *notebook; - GtkWidget *vbox_notebook, *vbox_terminal; - - if (!vbox) - return RC_BAD_PARAM; - - notebook = gtk_notebook_new(); - - vbox_notebook = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - ui_tree_view_create(NULL, vbox_notebook); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_notebook, NULL); - gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(notebook), vbox_notebook, "Messages list"); - -#if defined (FILTERS_TAB) - vbox_notebook = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_notebook, NULL); - gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(notebook), vbox_notebook, "Filters"); -#endif - - vbox_notebook = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox_notebook, NULL); - gtk_notebook_set_tab_label_text (GTK_NOTEBOOK(notebook), vbox_notebook, "Terminal"); - - vbox_terminal = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); - - terminal_view = ui_signal_dissect_new(vbox_terminal); - - gtk_box_pack_start (GTK_BOX(vbox_notebook), vbox_terminal, TRUE, TRUE, 5); - - /* Add the notebook to the vbox of the main window */ - gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); - - return RC_OK; -} diff --git a/common/utils/itti_analyzer/libui/ui_notebook.h b/common/utils/itti_analyzer/libui/ui_notebook.h deleted file mode 100644 index 6f87856e84..0000000000 --- a/common/utils/itti_analyzer/libui/ui_notebook.h +++ /dev/null @@ -1,31 +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 - */ - -#ifndef UI_NOTEBOOK_H_ -#define UI_NOTEBOOK_H_ - -void ui_notebook_terminal_clear(void); - -int ui_notebook_create(GtkWidget *vbox); - -void ui_notebook_terminal_append_data(gchar *text, gint length); - -#endif /* UI_NOTEBOOK_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_notif_dlg.c b/common/utils/itti_analyzer/libui/ui_notif_dlg.c deleted file mode 100644 index 4be4aa52cf..0000000000 --- a/common/utils/itti_analyzer/libui/ui_notif_dlg.c +++ /dev/null @@ -1,83 +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 - */ - -#define G_LOG_DOMAIN ("UI") - -#include "rc.h" - -#include "ui_notif_dlg.h" -#include "ui_main_screen.h" - -static const char * const gtk_response_strings[] = - {"GTK_RESPONSE_NONE", "GTK_RESPONSE_REJECT", "GTK_RESPONSE_ACCEPT", "GTK_RESPONSE_DELETE_EVENT", "GTK_RESPONSE_OK", - "GTK_RESPONSE_CANCEL", "GTK_RESPONSE_CLOSE", "GTK_RESPONSE_YES", "GTK_RESPONSE_NO", "GTK_RESPONSE_APPLY", "GTK_RESPONSE_HELP"}; - -static const char * const title_type_strings[] = - {"Info", "Warning", "Question", "Error", "Other"}; - -const char * gtk_get_respose_string (gint response) -{ - gint response_index = - response - 1; - - if ((0 <= response_index) && (response_index < (sizeof (gtk_response_strings) / sizeof (gtk_response_strings[0])))) - { - return (gtk_response_strings[response_index]); - } - else - { - return ("Invalid response value!"); - } -} -int ui_notification_dialog(GtkMessageType type, gboolean cancel, const char *title, const char *fmt, ...) -{ - va_list args; - GtkWidget *dialogbox; - char buffer[200]; - int result = RC_OK; - - va_start(args, fmt); - - vsnprintf (buffer, sizeof(buffer), fmt, args); - - g_warning("%s", buffer); - - dialogbox = gtk_message_dialog_new (GTK_WINDOW(ui_main_data.window), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL, type, - cancel ? GTK_BUTTONS_OK_CANCEL : GTK_BUTTONS_OK, "%s", - buffer); - /* Set the window at center of main window */ - gtk_window_set_position (GTK_WINDOW(dialogbox), GTK_WIN_POS_CENTER_ON_PARENT); - - gtk_dialog_set_default_response (GTK_DIALOG(dialogbox), GTK_RESPONSE_OK); - - snprintf (buffer, sizeof(buffer), "%s: %s", title_type_strings[type], title); - gtk_window_set_title (GTK_WINDOW(dialogbox), buffer); - - if (gtk_dialog_run (GTK_DIALOG (dialogbox)) == GTK_RESPONSE_CANCEL) - { - result = RC_FAIL; - } - - gtk_widget_destroy (dialogbox); - - va_end(args); - - return result; -} diff --git a/common/utils/itti_analyzer/libui/ui_notif_dlg.h b/common/utils/itti_analyzer/libui/ui_notif_dlg.h deleted file mode 100644 index 361ec81850..0000000000 --- a/common/utils/itti_analyzer/libui/ui_notif_dlg.h +++ /dev/null @@ -1,31 +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 - */ - -#include - -#ifndef UI_NOTIF_DLG_H_ -#define UI_NOTIF_DLG_H_ - -const char *gtk_get_respose_string (gint response); - -extern int ui_notification_dialog(GtkMessageType type, gboolean cancel, const char *title, const char *fmt, ...); - -#endif /* UI_NOTIF_DLG_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_notifications.c b/common/utils/itti_analyzer/libui/ui_notifications.c deleted file mode 100644 index 6e7897c850..0000000000 --- a/common/utils/itti_analyzer/libui/ui_notifications.c +++ /dev/null @@ -1,636 +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 - */ - -#include -#include -#include -#include - -#define G_LOG_DOMAIN ("UI") - -#include - -#include - -#include "logs.h" -#include "itti_types.h" -#include "rc.h" - -#include "ui_interface.h" -#include "ui_main_screen.h" -#include "ui_menu_bar.h" -#include "ui_notifications.h" -#include "ui_notif_dlg.h" -#include "ui_callbacks.h" -#include "ui_filters.h" -#include "ui_tree_view.h" - -#include "locate_root.h" -#include "xml_parse.h" -#include "socket.h" - -static const itti_message_types_t itti_dump_xml_definition_end = ITTI_DUMP_XML_DEFINITION_END; -static const itti_message_types_t itti_dump_message_type_end = ITTI_DUMP_MESSAGE_TYPE_END; - -static FILE *messages_file; -static uint32_t message_number; -static gboolean ui_abort; - -int ui_disable_connect_button(void) -{ - /* Disable Connect button and enable disconnect button */ - gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.connect), FALSE); - gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.disconnect), TRUE); - socket_abort_connection = FALSE; - - return RC_OK; -} - -int ui_enable_connect_button(void) -{ - /* Disable Disconnect button and enable connect button */ - gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.connect), TRUE); - gtk_widget_set_sensitive (GTK_WIDGET (ui_main_data.disconnect), FALSE); - socket_abort_connection = TRUE; - ui_set_sensitive_save_message_buttons (TRUE); - ui_set_title (""); - - return RC_OK; -} - -static void ui_change_cursor(gboolean busy) -{ - static GdkWindow *window; - - if (busy) - { - GdkDisplay *display; - GdkCursor *cursor; - // gint x, y; - - cursor = gdk_cursor_new (GDK_WATCH); - display = gdk_display_get_default (); - window = gtk_widget_get_window (GTK_WIDGET(ui_main_data.window)); - // window = gdk_display_get_window_at_pointer(display, &x, &y); - - gdk_window_set_cursor (window, cursor); - gdk_display_sync (display); - g_object_unref (cursor); - // gtk_widget_set_sensitive (ui_main_data.window, FALSE); - ui_gtk_flush_events (); - } - else - { - gdk_window_set_cursor (window, NULL); - // gtk_widget_set_sensitive (ui_main_data.window, TRUE); - ui_gtk_flush_events (); - } -} - -static void gtk_filter_add(GtkWidget *file_chooser, const gchar *title, const gchar *pattern) -{ - GtkFileFilter *file_filter = gtk_file_filter_new (); - - gtk_file_filter_set_name (file_filter, title); - gtk_file_filter_add_pattern (file_filter, pattern); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER(file_chooser), file_filter); -} - -int ui_messages_read(char *file_name) -{ - int result = RC_OK; - int source; - int read_data = 0; - void *input_data = NULL; - size_t input_data_length = 0; - int read_messages = 0; - - ui_change_cursor (TRUE); - - source = open (file_name, O_RDONLY); - if (source < 0) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages", "Failed to open file \"%s\": %s", file_name, - g_strerror (errno)); - result = RC_FAIL; - } - else - { - itti_socket_header_t message_header; - struct stat st; - int size; - double read_fraction = 0.f; - - if (stat (file_name, &st) < 0) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "get file length", - "Failed to retrieve length for file \"%s\": %s", file_name, g_strerror (errno)); - result = RC_FAIL; - } - size = st.st_size; - - ui_callback_signal_clear_list (NULL, NULL); - - /* Initialize the progress bar */ - ui_abort = FALSE; - ui_progress_bar_set_fraction (0); - - do - { - read_data = read (source, &message_header, sizeof(itti_socket_header_t)); - - if (read_data == -1) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages", "Failed to read from file \"%s\": %s", - file_name, g_strerror (errno)); - result = RC_FAIL; - break; - } - - if (read_data == 0) - { - break; - } - - if (read_data < sizeof(itti_socket_header_t)) - { - if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages", - "Failed to read a complete message header from file \"%s\": %s", file_name, g_strerror (errno)) == RC_FAIL) - { - read_data = 0; - } - } - else - { - read_fraction += (double) read_data / size; - - input_data_length = message_header.message_size - sizeof(itti_socket_header_t); - - g_debug("%x, %x, %zd", message_header.message_type, message_header.message_size, input_data_length); - - /* Checking for non-header part */ - if (input_data_length > 0) - { - input_data = malloc (input_data_length); - - read_data = read (source, input_data, input_data_length); - if (read_data < input_data_length) - { - if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages", - "Failed to read a complete message from file \"%s\": %s", file_name, g_strerror (errno)) == RC_FAIL) - { - read_data = 0; - } - break; - } - - read_fraction += (double) input_data_length / size; - } - - switch (message_header.message_type) - { - case ITTI_DUMP_XML_DEFINITION: - ui_gtk_flush_events (); - if (memcmp (&(((char *) input_data)[input_data_length - sizeof (itti_message_types_t)]), - &itti_dump_xml_definition_end, sizeof (itti_message_types_t)) == 0) - { - result = xml_parse_buffer (input_data, input_data_length - sizeof (itti_message_types_t)); - if (result != RC_OK) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages", - "Error in parsing XML definitions in file \"%s\": %s", file_name, - rc_strings[-result]); - read_data = 0; - } - ui_gtk_flush_events (); - g_message("Parsed XML definition from file \"%s\"", file_name); - } - else - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "open messages", - "Error in parsing XML definitions in file \"%s\", end mark is missing", file_name); - } - /* Data input buffer is kept in case user when to save the log file later */ - break; - - case ITTI_DUMP_MESSAGE_TYPE: - { - itti_signal_header_t *itti_signal_header = input_data; - buffer_t *buffer; - - if (memcmp (&(((char *) input_data)[input_data_length - sizeof (itti_message_types_t)]), - &itti_dump_message_type_end, sizeof (itti_message_types_t)) == 0) - { - /* Create the new buffer */ - if (buffer_new_from_data (&buffer, input_data + sizeof(itti_signal_header_t), - input_data_length - sizeof(itti_signal_header_t) - sizeof(itti_message_types_t), 0) != RC_OK) - { - g_error("Failed to create new buffer"); - g_assert_not_reached (); - } - - sscanf (itti_signal_header->message_number_char, MESSAGE_NUMBER_CHAR_FORMAT, &buffer->message_number); - - ui_signal_add_to_list (buffer, ((read_messages % 1000) == 0) ? (gpointer) 1 : NULL); - - if ((read_messages % 100) == 0) - { - ui_progress_bar_set_fraction (read_fraction); - ui_gtk_flush_events (); - } - - read_messages++; - } - else - { - if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages", - "Failed to read a message from file \"%s\", end mark is missing", file_name) == RC_FAIL) - { - read_data = 0; - } - break; - } - - free (input_data); - break; - } - - case ITTI_STATISTIC_MESSAGE_TYPE: - default: - if (ui_notification_dialog (GTK_MESSAGE_WARNING, TRUE, "open messages", - "Unknown (or not implemented) record type: %d in file \"%s\"", - message_header.message_type, file_name) == RC_FAIL) - { - read_data = 0; - } - - free (input_data); - break; - } - } - } while ((ui_abort == FALSE) && (read_data > 0)); - - if (read_messages > 0) - { - char *basename; - - /* Enable buttons to move in the list of signals */ - ui_set_sensitive_move_buttons (TRUE); - - if (ui_main_data.follow_last) - { - /* Advance to the last signal */ - ui_tree_view_select_row (ui_tree_view_get_filtered_number () - 1); - } - - basename = g_path_get_basename (file_name); - ui_set_title ("\"%s\"", basename); - } - else - { - result = RC_FAIL; - } - - ui_progress_bar_terminate (); - - g_message("Read %d messages (%d to display) from file \"%s\"\n", read_messages, ui_tree_view_get_filtered_number(), file_name); - - close (source); - } - - ui_change_cursor (FALSE); - - return result; -} - -static void ui_message_write_callback(const gpointer buffer, const gchar *signal_name) -{ - buffer_t *signal_buffer = (buffer_t *) buffer; - itti_socket_header_t message_header; - itti_signal_header_t itti_signal_header; - uint32_t message_size; - - message_size = signal_buffer->size_bytes; - - message_header.message_size = sizeof(itti_socket_header_t) + sizeof(itti_signal_header) + message_size + sizeof(itti_message_types_t); - message_header.message_type = ITTI_DUMP_MESSAGE_TYPE; - - sprintf(itti_signal_header.message_number_char, MESSAGE_NUMBER_CHAR_FORMAT, message_number); - itti_signal_header.message_number_char[sizeof(itti_signal_header.message_number_char) - 1] = '\n'; - message_number++; - - fwrite (&message_header, sizeof(message_header), 1, messages_file); - fwrite (&itti_signal_header, sizeof(itti_signal_header), 1, messages_file); - fwrite (signal_buffer->data, message_size, 1, messages_file); - fwrite (&itti_dump_message_type_end, sizeof(itti_message_types_t), 1, messages_file); -} - -static int ui_messages_file_write(char *file_name, gboolean filtered) -{ - if (file_name == NULL) - { - g_warning("No name for log file"); - return RC_FAIL; - } - - messages_file = fopen (file_name, "w"); - if (messages_file == NULL) - { - ui_notification_dialog (GTK_MESSAGE_ERROR, FALSE, "Failed to open file \"%s\": %s", file_name, g_strerror (errno)); - return RC_FAIL; - } - - /* Write XML definitions */ - { - itti_socket_header_t message_header; - - message_header.message_size = sizeof(itti_socket_header_t) + xml_raw_data_size + sizeof(itti_message_types_t); - message_header.message_type = ITTI_DUMP_XML_DEFINITION; - - fwrite (&message_header, sizeof(message_header), 1, messages_file); - fwrite (xml_raw_data, xml_raw_data_size, 1, messages_file); - fwrite (&itti_dump_xml_definition_end, sizeof(itti_message_types_t), 1, messages_file); - } - - /* Write messages */ - { - message_number = 1; - ui_tree_view_foreach_message (ui_message_write_callback, filtered); - } - - fclose (messages_file); - - return RC_OK; -} - -int ui_messages_open_file_chooser(void) -{ - int result = RC_OK; - - GtkWidget *filechooser; - gboolean response_accept; - char *filename; - - filechooser = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (ui_main_data.window), - GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); - gtk_filter_add (filechooser, "Log files", "*.log"); - gtk_filter_add (filechooser, "All files", "*"); - - /* Process the response */ - response_accept = gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT; - - if (response_accept) - { - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); - } - gtk_widget_destroy (filechooser); - if (response_accept) - { - ui_set_sensitive_save_message_buttons (FALSE); - - result = ui_messages_read (filename); - if (result == RC_OK) - { - /* Update messages file name for future use */ - if (ui_main_data.messages_file_name != NULL) - { - g_free (ui_main_data.messages_file_name); - } - ui_main_data.messages_file_name = filename; - - ui_set_sensitive_save_message_buttons (TRUE); - } - else - { - g_free (filename); - } - } - return result; -} - -int ui_messages_save_file_chooser(gboolean filtered) -{ - int result = RC_OK; - GtkWidget *filechooser; - - /* Check if there is something to save */ - if (xml_raw_data_size > 0) - { - static const char *title[] = - { - "Save file (all messages)", - "Save file (filtered messages)", - }; - - filechooser = gtk_file_chooser_dialog_new (title[filtered], GTK_WINDOW (ui_main_data.window), - GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); - gtk_filter_add (filechooser, "Log files", "*.log"); - gtk_filter_add (filechooser, "All files", "*"); - - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (filechooser), TRUE); - - if (ui_main_data.messages_file_name != NULL) - { - gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser), ui_main_data.messages_file_name); - } - else - { - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filechooser), "messages.log"); - } - - /* Process the response */ - if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT) - { - char *filename; - - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); - result = ui_messages_file_write (filename, filtered); - if (result == RC_OK) - { - /* Update filters file name for future use */ - if (ui_main_data.messages_file_name != NULL) - { - g_free (ui_main_data.messages_file_name); - } - ui_main_data.messages_file_name = filename; - } - else - { - g_free (filename); - } - } - gtk_widget_destroy (filechooser); - } - - return result; -} - -int ui_filters_open_file_chooser(void) -{ - int result = RC_OK; - GtkWidget *filechooser; - gboolean response_accept; - char *filename; - - filechooser = gtk_file_chooser_dialog_new ("Select file", GTK_WINDOW (ui_main_data.window), - GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); - gtk_filter_add (filechooser, "Filters files", "*.xml"); - gtk_filter_add (filechooser, "All files", "*"); - - /* Process the response */ - response_accept = gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT; - - if (response_accept) - { - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); - } - gtk_widget_destroy (filechooser); - if (response_accept) - { - result = ui_filters_read (filename); - if (result == RC_OK) - { - /* Update filters file name for future use */ - if (ui_main_data.filters_file_name != NULL) - { - g_free (ui_main_data.filters_file_name); - } - ui_main_data.filters_file_name = filename; - } - else - { - g_free (filename); - } - } - - return result; -} - -int ui_filters_save_file_chooser(void) -{ - int result = RC_OK; - GtkWidget *filechooser; - - filechooser = gtk_file_chooser_dialog_new ("Save file", GTK_WINDOW (ui_main_data.window), - GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); - gtk_filter_add (filechooser, "Filters files", "*.xml"); - gtk_filter_add (filechooser, "All files", "*"); - - gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (filechooser), TRUE); - - if (ui_main_data.filters_file_name != NULL) - { - gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser), ui_main_data.filters_file_name); - } - else - { - gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (filechooser), "filters.xml"); - } - - /* Process the response */ - if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT) - { - char *filename; - - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); - result = ui_filters_file_write (filename); - if (result == RC_OK) - { - /* Update filters file name for future use */ - if (ui_main_data.filters_file_name != NULL) - { - g_free (ui_main_data.filters_file_name); - } - ui_main_data.filters_file_name = filename; - } - else - { - g_free (filename); - } - } - gtk_widget_destroy (filechooser); - - return result; -} - -void ui_progressbar_window_destroy (void) -{ - ui_abort = TRUE; - ui_progress_bar_terminate(); -} - -int ui_progress_bar_set_fraction(double fraction) -{ - if (ui_abort == FALSE) - { - /* If not exist instantiate */ - if (!ui_main_data.progressbar && !ui_main_data.progressbar_window) - { - ui_main_data.progressbar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - /* Keep progress bar window on top of main window */ - gtk_window_set_transient_for (GTK_WINDOW(ui_main_data.progressbar_window), GTK_WINDOW(ui_main_data.window)); - - /* Set the window at center of main window */ - gtk_window_set_position (GTK_WINDOW(ui_main_data.progressbar_window), GTK_WIN_POS_CENTER_ON_PARENT); - gtk_window_set_title (GTK_WINDOW(ui_main_data.progressbar_window), "Processing"); - - gtk_container_set_border_width (GTK_CONTAINER (ui_main_data.progressbar_window), 10); - - ui_main_data.progressbar = gtk_progress_bar_new (); - - gtk_container_add (GTK_CONTAINER (ui_main_data.progressbar_window), ui_main_data.progressbar); - - /* Assign the destroy event */ - g_signal_connect(ui_main_data.progressbar_window, "destroy", ui_progressbar_window_destroy, NULL); - - gtk_widget_show_all (ui_main_data.progressbar_window); - - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.stop_loading), TRUE); - } - - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(ui_main_data.progressbar), fraction); - -// ui_gtk_flush_events(); - } - - return RC_OK; -} - -int ui_progress_bar_terminate(void) -{ - if (ui_main_data.progressbar) - { - gtk_widget_destroy (ui_main_data.progressbar); - ui_main_data.progressbar = NULL; - } - if (ui_main_data.progressbar_window) - { - gtk_widget_destroy (ui_main_data.progressbar_window); - ui_main_data.progressbar_window = NULL; - } - gtk_widget_set_sensitive(GTK_WIDGET(ui_main_data.stop_loading), FALSE); - - return RC_OK; -} diff --git a/common/utils/itti_analyzer/libui/ui_signal_dissect_view.c b/common/utils/itti_analyzer/libui/ui_signal_dissect_view.c deleted file mode 100644 index 859eb66b03..0000000000 --- a/common/utils/itti_analyzer/libui/ui_signal_dissect_view.c +++ /dev/null @@ -1,117 +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 - */ - -#include - -#define G_LOG_DOMAIN ("UI") - -#include - -#include "rc.h" - -#include "ui_main_screen.h" -#include "ui_menu_bar.h" -#include "ui_signal_dissect_view.h" - -ui_text_view_t *ui_signal_dissect_new(GtkWidget *hbox) -{ - GtkWidget *scrolled_window; - ui_text_view_t *new_text_view; - - new_text_view = malloc(sizeof(ui_text_view_t)); - - new_text_view->text_view = gtk_text_view_new(); - scrolled_window = gtk_scrolled_window_new(NULL, NULL); - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - - /* Change the font of the widget */ - new_text_view->text_view_font = pango_font_description_new(); - - g_debug("Default family is: %s\n", pango_font_description_get_family(new_text_view->text_view_font)); - - pango_font_description_set_family(new_text_view->text_view_font, "Monospace"); - pango_font_description_set_absolute_size(new_text_view->text_view_font, 10 * PANGO_SCALE); - - g_debug("Font family has been set to: %s\n", pango_font_description_get_family(new_text_view->text_view_font)); - - gtk_widget_override_font(new_text_view->text_view, new_text_view->text_view_font); - - /* Disable editable attribute */ - gtk_text_view_set_editable(GTK_TEXT_VIEW(new_text_view->text_view), FALSE); - - gtk_container_add(GTK_CONTAINER(scrolled_window), new_text_view->text_view); - - gtk_paned_pack2 (GTK_PANED (hbox), scrolled_window, TRUE, FALSE); - - return new_text_view; -} - -int ui_signal_dissect_clear_view(ui_text_view_t *text_view) -{ - GtkTextBuffer *text_buffer; - - g_assert(text_view != NULL); - - if (text_view->text_view != NULL) - { - /* Create an empty text buffer */ - text_buffer = gtk_text_buffer_new(NULL); - gtk_text_buffer_set_text(text_buffer, "", 0); - - gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_view->text_view), text_buffer); - } - - return RC_OK; -} - -gboolean ui_signal_set_text(gpointer user_data, gchar *text, gint length) -{ - GtkTextBuffer *text_buffer; - ui_text_view_t *text_view; - - if (length < 0) - return FALSE; - - text_view = (ui_text_view_t *)user_data; - - g_assert(text != NULL); - g_assert(text_view != NULL); - g_assert(text_view->text_view != NULL); - - g_assert(GTK_IS_TEXT_VIEW(GTK_TEXT_VIEW(text_view->text_view))); - - text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view->text_view)); - - if (text_buffer) { - /* We already have a text buffer, use it */ - gtk_text_buffer_insert_at_cursor(text_buffer, text, length); - } else { - /* No buffer currently in use, create a new one */ - text_buffer = gtk_text_buffer_new(NULL); - gtk_text_buffer_set_text(text_buffer, text, length); - gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_view->text_view), - text_buffer); - } - - return TRUE; -} diff --git a/common/utils/itti_analyzer/libui/ui_tree_view.c b/common/utils/itti_analyzer/libui/ui_tree_view.c deleted file mode 100644 index 0396e24819..0000000000 --- a/common/utils/itti_analyzer/libui/ui_tree_view.c +++ /dev/null @@ -1,610 +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 - */ - -#include -#include - -#define G_LOG_DOMAIN ("UI_TREE") - -#include - -#include "logs.h" -#include "rc.h" - -#include "buffers.h" - -#include "ui_main_screen.h" -#include "ui_tree_view.h" -#include "ui_callbacks.h" -#include "ui_filters.h" - -#include "ui_signal_dissect_view.h" - -typedef struct -{ - GtkListStore *store; - GtkTreeModelFilter *filtered; - uint32_t filtered_last_msg; - uint32_t filtered_msg_number; - uint32_t instance_number; -} ui_store_t; - -static ui_store_t ui_store; - -GtkWidget *ui_tree_view_menu; -ui_tree_view_menu_enable_t ui_tree_view_menu_enable[NUM_MENU_TYPE]; - -GdkEventButton *ui_tree_view_last_event; - -static gboolean ui_tree_filter_messages(GtkTreeModel *model, GtkTreeIter *iter, ui_store_t *store) -{ - uint32_t msg_number; - uint32_t message_id; - uint32_t origin_task_id; - uint32_t destination_task_id; - uint32_t instance; - - gboolean enabled = TRUE; - - if (ui_filters.filters_enabled) - { - gtk_tree_model_get (model, iter, COL_MSG_NUM, &msg_number, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID, - &origin_task_id, COL_TO_TASK_ID, &destination_task_id, COL_INSTANCE_ID, &instance, -1); - if (msg_number != 0) - { - enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance); - - if ((enabled) && (store->filtered_last_msg < msg_number)) - { - store->filtered_last_msg = msg_number; - store->filtered_msg_number++; - } - g_debug("ui_tree_filter_messages: %p %p %d m:%d o:%d d:%d i:%d %d %d", model, iter, msg_number, message_id, origin_task_id, destination_task_id, instance, enabled, store->filtered_msg_number); - } - } - - return enabled; -} - -static gboolean onButtonPressed(GtkWidget *treeview, GdkEventButton *event, gpointer userdata) -{ - g_info("onButtonPressed %p %p %p %d %d", treeview, event, userdata, event->type, event->button); - ui_tree_view_last_event = event; - - return FALSE; -} - -/* - static gboolean onButtonRelease(GtkWidget *treeview, GdkEventButton *event, gpointer userdata) - { - g_info("onButtonRelease %p %p %p %d %d", treeview, event, userdata, event->type, event->button); - // last_event = event; - - return FALSE; - } - */ - -static void ui_tree_view_init_list(GtkWidget *list) -{ - GtkCellRenderer *renderer_left; - GtkCellRenderer *renderer_right; - GtkTreeViewColumn *column; - - renderer_left = gtk_cell_renderer_text_new (); - gtk_cell_renderer_set_padding (renderer_left, 5, 0); - - renderer_right = gtk_cell_renderer_text_new (); - gtk_cell_renderer_set_alignment (renderer_right, 1, 0.5); - gtk_cell_renderer_set_padding (renderer_right, 5, 0); - - column = gtk_tree_view_column_new_with_attributes ("MN", renderer_right, "text", COL_MSG_NUM, "foreground", - COL_FOREGROUND, "background", COL_BACKGROUND, NULL); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_append_column (GTK_TREE_VIEW(list), column); - - column = gtk_tree_view_column_new_with_attributes ("LTE Time", renderer_right, "text", COL_LTE_TIME, NULL); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_append_column (GTK_TREE_VIEW(list), column); - - column = gtk_tree_view_column_new_with_attributes ("Message", renderer_left, "text", COL_MESSAGE, "foreground", - COL_FOREGROUND, "background", COL_BACKGROUND, "strikethrough", - COL_STRIKETHROUGH, "style", COL_STYLE, "weight", COL_WEIGHT, "underline", COL_UNDERLINE, NULL); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_append_column (GTK_TREE_VIEW(list), column); - g_signal_connect(G_OBJECT(column), "clicked", G_CALLBACK(ui_callback_on_tree_column_header_click), - (gpointer) COL_MESSAGE); - - column = gtk_tree_view_column_new_with_attributes ("From", renderer_left, "text", COL_FROM_TASK, NULL); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_append_column (GTK_TREE_VIEW(list), column); - g_signal_connect(G_OBJECT(column), "clicked", G_CALLBACK(ui_callback_on_tree_column_header_click), - (gpointer) COL_FROM_TASK); - - column = gtk_tree_view_column_new_with_attributes ("To", renderer_left, "text", COL_TO_TASK, NULL); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_column_set_resizable (column, TRUE); - gtk_tree_view_append_column (GTK_TREE_VIEW(list), column); - g_signal_connect(G_OBJECT(column), "clicked", G_CALLBACK(ui_callback_on_tree_column_header_click), - (gpointer) COL_TO_TASK); - - column = gtk_tree_view_column_new_with_attributes ("Ins", renderer_right, "text", COL_INSTANCE, NULL); - gtk_tree_view_column_set_alignment (column, 0.5); - gtk_tree_view_append_column (GTK_TREE_VIEW(list), column); - g_signal_connect(G_OBJECT(column), "clicked", G_CALLBACK(ui_callback_on_tree_column_header_click), - (gpointer) COL_INSTANCE); - - ui_store.store = gtk_list_store_new (NUM_COLS, // Number of columns - // Displayed columns - G_TYPE_UINT, // COL_MSG_NUM - G_TYPE_STRING, // COL_LTE_TIME - G_TYPE_STRING, // COL_MESSAGE - G_TYPE_STRING, // COL_FROM_TASK - G_TYPE_STRING, // COL_TO_TASK - G_TYPE_STRING, // COL_INSTANCE - // Not displayed columns - // Id of some message fields to speed-up filtering - G_TYPE_UINT, // COL_MESSAGE_ID - G_TYPE_UINT, // COL_FROM_TASK_ID - G_TYPE_UINT, // COL_TO_TASK_ID - G_TYPE_UINT, // COL_INSTANCE_ID - G_TYPE_STRING, // COL_FOREGROUND - G_TYPE_STRING, // COL_BACKGROUND - G_TYPE_BOOLEAN, // COL_STRIKETHROUGH - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT, - // Reference to the buffer here to avoid maintaining multiple lists. - G_TYPE_POINTER); - - if (ui_store.store == NULL) - { - g_error("gtk_list_store_new failed"); - } - - ui_store.filtered = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (ui_store.store), NULL)); - gtk_tree_model_filter_set_visible_func (ui_store.filtered, (GtkTreeModelFilterVisibleFunc) ui_tree_filter_messages, - &ui_store, NULL); - - gtk_tree_view_set_model (GTK_TREE_VIEW(list), GTK_TREE_MODEL(ui_store.filtered)); - - gtk_tree_view_columns_autosize (GTK_TREE_VIEW(list)); -} - -static void ui_tree_view_add_to_list(GtkWidget *list, const gchar *lte_time, const uint32_t message_number, - const uint32_t message_id, const gchar *signal_name, const uint32_t origin_task_id, - const char *origin_task_name, const uint32_t destination_task_id, - const char *destination_task_name, uint32_t instance_id, const char *instance_name, gpointer buffer) -{ - static int counter = 0; - - GtkTreeIter iter; - gboolean enabled; - int message_index; - - g_info("ui_tree_view_add_to_list: %d %d %d %d %d", message_number, message_id, origin_task_id, destination_task_id, instance_id); - - enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance_id); - message_index = ui_filters_search_id (&ui_filters.messages, message_id); - - g_info("ui_tree_view_add_to_list: %d %d", enabled, message_index); - - gtk_list_store_append (ui_store.store, &iter); - gtk_list_store_set (ui_store.store, &iter, - /* Columns */ - COL_MSG_NUM, - message_number, COL_LTE_TIME, lte_time, COL_MESSAGE, signal_name, COL_FROM_TASK, origin_task_name, - COL_TO_TASK, destination_task_name, COL_INSTANCE, instance_name, COL_MESSAGE_ID, message_id, - COL_FROM_TASK_ID, origin_task_id, COL_TO_TASK_ID, destination_task_id, COL_INSTANCE_ID, instance_id, - COL_BUFFER, buffer, COL_FOREGROUND, ui_filters.messages.items[message_index].foreground, COL_BACKGROUND, - ui_filters.messages.items[message_index].background, COL_STRIKETHROUGH, !enabled, -// COL_STYLE, (counter % 2) == 0 ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL, -// COL_WEIGHT, ((counter + 2) % 4) < 2 ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -// COL_UNDERLINE, ((counter + 4) % 8) < 4 ?PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE, - COL_STYLE, PANGO_STYLE_NORMAL, - COL_WEIGHT, PANGO_WEIGHT_NORMAL, - COL_UNDERLINE, PANGO_UNDERLINE_NONE, - /* End of columns */ - -1); - counter++; -} - -void ui_tree_view_destroy_list(GtkWidget *list) -{ - g_assert(list != NULL); - - gtk_list_store_clear (ui_store.store); - ui_store.filtered_last_msg = 0; - ui_store.filtered_msg_number = 0; - ui_store.instance_number = 0; - - /* Reset number of messages */ - ui_main_data.nb_message_received = 0; -} - -/* Search for the message with its message number equal to the given value or the previous one */ -static gboolean ui_tree_view_search(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, - gpointer search_data) -{ - uint32_t msg_number; - uint32_t key_value = atoi (key); - - gtk_tree_model_get (model, iter, column, &msg_number, -1); - - g_debug("ui_tree_view_search %d %d", key_value, msg_number); - - if (key_value == msg_number) - { - /* Value found, use this message */ - return 0; - } - - { - GtkTreeIter iter_next = *iter; - - if (gtk_tree_model_iter_next (model, &iter_next)) - { - gtk_tree_model_get (model, &iter_next, column, &msg_number, -1); - - if (key_value < msg_number) - { - /* Next value will be greater, use this message */ - return 0; - } - } - else - { - /* Last value, use this message */ - return 0; - } - } - return 1; -} - -static void ui_tree_view_create_menu(GtkWidget **menu) -{ - GtkWidget *menu_items; - - *menu = gtk_menu_new (); - - /* Create the "Message enable" menu-item */ - { - /* Create a new menu-item */ - menu_items = gtk_check_menu_item_new (); - ui_tree_view_menu_enable[MENU_MESSAGE].menu_enable = menu_items; - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable), - &ui_tree_view_menu_enable[MENU_MESSAGE]); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create the "Destination task enable" menu-item */ - { - /* Create a new menu-item */ - menu_items = gtk_check_menu_item_new (); - ui_tree_view_menu_enable[MENU_FROM_TASK].menu_enable = menu_items; - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable), - &ui_tree_view_menu_enable[MENU_FROM_TASK]); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create the "Origin task enable" menu-item */ - { - /* Create a new menu-item */ - menu_items = gtk_check_menu_item_new (); - ui_tree_view_menu_enable[MENU_TO_TASK].menu_enable = menu_items; - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable), - &ui_tree_view_menu_enable[MENU_TO_TASK]); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create the "Instance enable" menu-item */ - { - /* Create a new menu-item */ - menu_items = gtk_check_menu_item_new (); - ui_tree_view_menu_enable[MENU_INSTANCE].menu_enable = menu_items; - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_enable), - &ui_tree_view_menu_enable[MENU_INSTANCE]); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create the "Foreground color" menu-item */ - { - static ui_tree_view_menu_color_t menu_color_foreground = - {TRUE, &ui_tree_view_menu_enable[MENU_MESSAGE]}; - - /* Create a new menu-item with a name */ - menu_items = gtk_menu_item_new_with_label ("Select message foreground color"); - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_color), - &menu_color_foreground); - - /* Show the widget */ - gtk_widget_show (menu_items); - } - - /* Create the "Background color" menu-item */ - { - static ui_tree_view_menu_color_t menu_color_background = - {FALSE, &ui_tree_view_menu_enable[MENU_MESSAGE]}; - - /* Create a new menu-item with a name */ - menu_items = gtk_menu_item_new_with_label ("Select message background color"); - - /* Add it to the menu. */ - gtk_menu_shell_append (GTK_MENU_SHELL(*menu), menu_items); - g_signal_connect(G_OBJECT(menu_items), "activate", G_CALLBACK(ui_callback_on_menu_color), - &menu_color_background); - - /* Show the widget */ - gtk_widget_show (menu_items); - } -} - -int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox) -{ - GtkWidget *hbox; - GtkTreeSelection *selection; - GtkWidget *scrolled_window; - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - - ui_main_data.messages_list = gtk_tree_view_new (); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(ui_main_data.messages_list), TRUE); - gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW(ui_main_data.messages_list), ui_tree_view_search, NULL, NULL); - gtk_tree_view_set_search_entry (GTK_TREE_VIEW(ui_main_data.messages_list), - GTK_ENTRY(ui_main_data.signals_go_to_entry)); - - /* Disable multiple selection */ - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(ui_main_data.messages_list)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - - hbox = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL); - - gtk_container_add (GTK_CONTAINER(scrolled_window), ui_main_data.messages_list); - - ui_tree_view_init_list (ui_main_data.messages_list); - gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW(ui_main_data.messages_list), TRUE); - - gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW(scrolled_window), 680); - gtk_paned_pack1 (GTK_PANED (hbox), scrolled_window, FALSE, TRUE); - ui_main_data.text_view = ui_signal_dissect_new (hbox); - - gtk_box_pack_start (GTK_BOX(vbox), hbox, TRUE, TRUE, 5); - - g_signal_connect(G_OBJECT(ui_main_data.messages_list), "button-press-event", G_CALLBACK (onButtonPressed), NULL); - // g_signal_connect(G_OBJECT(ui_main_data.signalslist), "button-release-event", G_CALLBACK (onButtonRelease), NULL); - - /* Connect callback on row selection */ - gtk_tree_selection_set_select_function (selection, ui_callback_on_select_signal, ui_main_data.text_view, NULL); - - ui_store.filtered_last_msg = 0; - ui_store.filtered_msg_number = 0; - ui_store.instance_number = 0; - - ui_main_data.selection = selection; - - ui_tree_view_create_menu (&ui_tree_view_menu); - - return 0; -} - -int ui_tree_view_new_signal_ind(const uint32_t message_number, const gchar *lte_time, const uint32_t message_id, - const char *message_name, const uint32_t origin_task_id, const char *origin_task_name, - const uint32_t destination_task_id, const char *destination_task_name, uint32_t instance_id, - gpointer buffer) -{ - char *instance_name = NULL; - char instance_name_buffer[10]; - - if (((instance_t) instance_id) < INSTANCE_DEFAULT) - { - if (ui_store.instance_number < (instance_id + 1)) - { - int i; - - for (i = ui_store.instance_number; i <= instance_id; i++) - { - sprintf (instance_name_buffer, "%d", i); - ui_filters_add (FILTER_INSTANCES, i, instance_name_buffer, ENTRY_ENABLED_TRUE, NULL, NULL); - } - ui_store.instance_number = (instance_id + 1); - ui_destroy_filter_menu (FILTER_INSTANCES); - } - - sprintf (instance_name_buffer, "%d", instance_id); - instance_name = instance_name_buffer; - } - else - { - switch ((instance_t) instance_id) - { - case INSTANCE_DEFAULT: - instance_name = "DEF"; - break; - - case INSTANCE_ALL: - instance_name = "ALL"; - break; - - default: - break; - } - - if ((instance_name != NULL) && (ui_filters_search_id (&ui_filters.instances, instance_id) < 0)) - { - ui_filters_add (FILTER_INSTANCES, instance_id, instance_name, ENTRY_ENABLED_TRUE, NULL, NULL); - } - } - - ui_tree_view_add_to_list (ui_main_data.messages_list, lte_time, message_number, message_id, message_name, - origin_task_id, origin_task_name, destination_task_id, destination_task_name, instance_id, instance_name, - buffer); - - return RC_OK; -} - -void ui_tree_view_select_row(gint row) -{ - GtkTreePath *path_row; - - if (row >= 0) - { - path_row = gtk_tree_path_new_from_indices (row, -1); - - if ((ui_main_data.messages_list != NULL) && (path_row != NULL)) - { - g_info("Select row %d", row); - - /* Select the message in requested row */ - gtk_tree_view_set_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), path_row, NULL, FALSE); - /* Center the message in the middle of the list if possible */ - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(ui_main_data.messages_list), path_row, NULL, TRUE, 0.5, 0.0); - } - } -} - -static gboolean updateColors(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) -{ - uint32_t message_id; - uint32_t origin_task_id; - uint32_t destination_task_id; - uint32_t instance; - - gboolean enabled = FALSE; - int message_index; - - gtk_tree_model_get (model, iter, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID, &origin_task_id, COL_TO_TASK_ID, - &destination_task_id, COL_INSTANCE_ID, &instance, -1); - enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance); - message_index = ui_filters_search_id (&ui_filters.messages, message_id); - - gtk_list_store_set (GTK_LIST_STORE(model), iter, COL_FOREGROUND, - ui_filters.messages.items[message_index].foreground, COL_BACKGROUND, - ui_filters.messages.items[message_index].background, COL_STRIKETHROUGH, !enabled, -1); - - return FALSE; -} - -void ui_tree_view_refilter() -{ - ui_store.filtered_last_msg = 0; - ui_store.filtered_msg_number = 0; - - /* Update foreground color of messages, this will also update filtered model */ - if (ui_store.store != NULL) - { - gtk_tree_model_foreach (GTK_TREE_MODEL(ui_store.store), updateColors, NULL); - - if (ui_main_data.messages_list != NULL) - { - GtkTreePath *path_row; - - /* Get the currently selected message */ - gtk_tree_view_get_cursor (GTK_TREE_VIEW(ui_main_data.messages_list), &path_row, NULL); - if (path_row != NULL) - { - /* Center the message in the middle of the list if possible */ - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(ui_main_data.messages_list), path_row, NULL, TRUE, 0.5, - 0.0); - g_info("ui_tree_view_refilter: center on message"); - } - } - } - - g_info("ui_tree_view_refilter: last message %d, %d messages displayed", ui_store.filtered_last_msg, ui_store.filtered_msg_number); -} - -typedef struct foreach_message_params_s -{ - message_write_callback_t callback; - gboolean filter; -} foreach_message_params_t; - -static gboolean foreach_message(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) -{ - foreach_message_params_t *params = (foreach_message_params_t *) data; - const gchar *signal_name; - uint32_t message_id; - uint32_t origin_task_id; - uint32_t destination_task_id; - uint32_t instance; - gpointer buffer = NULL; - - gtk_tree_model_get (model, iter, COL_MESSAGE, &signal_name, COL_MESSAGE_ID, &message_id, COL_FROM_TASK_ID, &origin_task_id, COL_TO_TASK_ID, - &destination_task_id, COL_INSTANCE_ID, &instance, COL_BUFFER, &buffer, -1); - - if (params->filter == TRUE) - { - gboolean enabled = FALSE; - - enabled = ui_filters_message_enabled (message_id, origin_task_id, destination_task_id, instance); - if (enabled == FALSE) - { - buffer = NULL; - } - } - - if (buffer != NULL) - { - params->callback(buffer, signal_name); - } - - return FALSE; -} - -void ui_tree_view_foreach_message(message_write_callback_t callback, gboolean filter) -{ - foreach_message_params_t params = {callback, filter}; - - gtk_tree_model_foreach (GTK_TREE_MODEL(ui_store.store), foreach_message, (void *) ¶ms); -} - -guint ui_tree_view_get_filtered_number(void) -{ - return ui_store.filtered_msg_number; -} diff --git a/common/utils/itti_analyzer/libui/ui_tree_view.h b/common/utils/itti_analyzer/libui/ui_tree_view.h deleted file mode 100644 index 88ab2fce71..0000000000 --- a/common/utils/itti_analyzer/libui/ui_tree_view.h +++ /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 - */ - -#ifndef UI_TREE_VIEW_H_ -#define UI_TREE_VIEW_H_ - -#include "ui_filters.h" -#include "ui_notifications.h" - -typedef enum col_type_e -{ - COL_MSG_NUM = 0, - COL_LTE_TIME, - COL_MESSAGE, - COL_FROM_TASK, - COL_TO_TASK, - COL_INSTANCE, - - COL_MESSAGE_ID, - COL_FROM_TASK_ID, - COL_TO_TASK_ID, - COL_INSTANCE_ID, - COL_FOREGROUND, - COL_BACKGROUND, - COL_STRIKETHROUGH, - COL_STYLE, - COL_WEIGHT, - COL_UNDERLINE, - - COL_BUFFER, - NUM_COLS -} col_type_t; - -typedef enum ui_tree_view_menu_type_e -{ - MENU_MESSAGE = 0, - MENU_FROM_TASK, - MENU_TO_TASK, - MENU_INSTANCE, - NUM_MENU_TYPE, -} ui_tree_view_menu_type_t; - -typedef struct ui_tree_view_menu_enable_s -{ - GtkWidget *menu_enable; - ui_filter_item_t *filter_item; -} ui_tree_view_menu_enable_t; - -typedef struct ui_tree_view_menu_color_s -{ - gboolean foreground; - ui_tree_view_menu_enable_t *menu_enable; -} ui_tree_view_menu_color_t; - -extern GtkWidget *ui_tree_view_menu; -extern ui_tree_view_menu_enable_t ui_tree_view_menu_enable[NUM_MENU_TYPE]; - -extern GdkEventButton *ui_tree_view_last_event; - -int ui_tree_view_create(GtkWidget *window, GtkWidget *vbox); - -int ui_tree_view_new_signal_ind(const uint32_t message_number, const gchar *lte_time, - const uint32_t message_id, const char *message_name, - const uint32_t origin_task_id, const char *origin_task, - const uint32_t destination_task_id, const char *to_task, - uint32_t instance, gpointer buffer); - -void ui_tree_view_destroy_list(GtkWidget *list); - -void ui_tree_view_select_row(gint row); - -void ui_tree_view_refilter(void); - -void ui_tree_view_foreach_message(message_write_callback_t callback, gboolean filter); - -guint ui_tree_view_get_filtered_number(void); - -#endif /* UI_TREE_VIEW_H_ */ diff --git a/common/utils/memory_pools.c b/common/utils/memory_pools.c deleted file mode 100644 index 9f37e47080..0000000000 --- a/common/utils/memory_pools.c +++ /dev/null @@ -1,490 +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 - */ - -#include "assertions.h" -#include "memory_pools.h" - -#if T_TRACER - #include - #include "T.h" -#endif - -/*------------------------------------------------------------------------------*/ -const static int mp_debug = 0; - -# define MP_DEBUG(x, args...) do { if (mp_debug) fprintf(stdout, "[MP][D]"x, ##args); fflush (stdout); } \ - while(0) - -/*------------------------------------------------------------------------------*/ -#ifndef CHARS_TO_UINT32 - #define CHARS_TO_UINT32(c1, c2, c3, c4) (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) -#endif - -#define MEMORY_POOL_ITEM_INFO_NUMBER 2 - -/*------------------------------------------------------------------------------*/ -typedef int32_t items_group_position_t; -typedef int32_t items_group_index_t; - -typedef union items_group_positions_u { - uint64_t all; - struct { - items_group_position_t put; - items_group_position_t get; - } ind; -} items_group_positions_t; - -typedef struct items_group_s { - items_group_position_t number_plus_one; - volatile uint32_t minimum; - volatile items_group_positions_t positions; - volatile items_group_index_t *indexes; -} items_group_t; - -/*------------------------------------------------------------------------------*/ -//static const items_group_position_t ITEMS_GROUP_POSITION_INVALID = -1; -static const items_group_index_t ITEMS_GROUP_INDEX_INVALID = -1; - -/*------------------------------------------------------------------------------*/ -typedef uint32_t pool_item_start_mark_t; -typedef uint32_t pool_item_end_mark_t; - -typedef uint32_t memory_pool_data_t; - -typedef uint32_t pool_start_mark_t; - -typedef uint32_t pools_start_mark_t; - -typedef uint8_t pool_id_t; -typedef uint8_t item_status_t; - -typedef struct memory_pool_item_start_s { - pool_item_start_mark_t start_mark; - - pool_id_t pool_id; - item_status_t item_status; - uint16_t info[MEMORY_POOL_ITEM_INFO_NUMBER]; -} memory_pool_item_start_t; - -typedef struct memory_pool_item_end_s { - pool_item_end_mark_t end_mark; -} memory_pool_item_end_t; - -typedef struct memory_pool_item_s { - memory_pool_item_start_t start; - memory_pool_data_t data[0]; - memory_pool_item_end_t end; -} memory_pool_item_t; - -typedef struct memory_pool_s { - pool_start_mark_t start_mark; - - pool_id_t pool_id; - uint32_t item_data_number; - uint32_t pool_item_size; - items_group_t items_group_free; - memory_pool_item_t *items; -} memory_pool_t; - - -typedef struct memory_pools_s { - pools_start_mark_t start_mark; - - uint32_t pools_number; - uint32_t pools_defined; - memory_pool_t *pools; -} memory_pools_t; - -/*------------------------------------------------------------------------------*/ -static const uint32_t MAX_POOLS_NUMBER = 20; -static const uint32_t MAX_POOL_ITEMS_NUMBER = 200 * 1000; -static const uint32_t MAX_POOL_ITEM_SIZE = 100 * 1000; - -static const pool_item_start_mark_t POOL_ITEM_START_MARK = CHARS_TO_UINT32 ('P', 'I', 's', 't'); -static const pool_item_end_mark_t POOL_ITEM_END_MARK = CHARS_TO_UINT32 ('p', 'i', 'E', 'N'); - -static const item_status_t ITEM_STATUS_FREE = 'F'; -static const item_status_t ITEM_STATUS_ALLOCATED = 'a'; - -static const pool_start_mark_t POOL_START_MARK = CHARS_TO_UINT32 ('P', '_', 's', 't'); - -static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P', 'S', 's', 't'); - -/*------------------------------------------------------------------------------*/ -static inline uint32_t items_group_number_items (items_group_t *items_group) { - return items_group->number_plus_one - 1; -} - -static inline uint32_t items_group_free_items (items_group_t *items_group) { - items_group_positions_t positions; - uint32_t free_items; - positions.all = items_group->positions.all; - free_items = items_group->number_plus_one + positions.ind.put - positions.ind.get; - free_items %= items_group->number_plus_one; - return free_items; -} - -static inline items_group_index_t items_group_get_free_item (items_group_t *items_group) { - items_group_position_t get_raw; - items_group_position_t put; - items_group_position_t get; - items_group_position_t free_items; - items_group_index_t index = ITEMS_GROUP_INDEX_INVALID; - /* Get current put position */ - put = items_group->positions.ind.put % items_group->number_plus_one; - /* Get current get position and increase it */ - get_raw = __sync_fetch_and_add (&items_group->positions.ind.get, 1); - get = get_raw % items_group->number_plus_one; - - if(put == get) { - /* No more item free, restore previous position */ - __sync_fetch_and_sub (&items_group->positions.ind.get, 1); - } else { - /* Get index at current get position */ - index = items_group->indexes[get]; - - if (index <= ITEMS_GROUP_INDEX_INVALID) { - /* Index has not yet been completely freed, restore previous get position */ - __sync_fetch_and_sub (&items_group->positions.ind.get, 1); - } else { - if (get_raw == items_group->number_plus_one) { - /* Wrap get position */ - __sync_fetch_and_sub (&items_group->positions.ind.get, items_group->number_plus_one); - } - - free_items = items_group_free_items(items_group); - - /* Updates minimum free items if needed */ - while (items_group->minimum > free_items) { - items_group->minimum = free_items; - } - - /* Clear index at current get position to indicate that item is free */ - items_group->indexes[get] = ITEMS_GROUP_INDEX_INVALID; - } - } - - return (index); -} - -static inline int items_group_put_free_item (items_group_t *items_group, items_group_index_t index) { - items_group_position_t put_raw; - items_group_position_t put; - /* Get current put position and increase it */ - put_raw = __sync_fetch_and_add (&items_group->positions.ind.put, 1); - put = put_raw % items_group->number_plus_one; - - if (put_raw == items_group->number_plus_one) { - /* Wrap position */ - __sync_fetch_and_sub (&items_group->positions.ind.put, items_group->number_plus_one); - } - - AssertError (items_group->indexes[put] <= ITEMS_GROUP_INDEX_INVALID, return (EXIT_FAILURE), - "Index at current put position (%d) is not marked as free (%d)!\n", put, items_group->number_plus_one); - /* Save freed item index at current put position */ - items_group->indexes[put] = index; - return (EXIT_SUCCESS); -} - -/*------------------------------------------------------------------------------*/ -static inline memory_pools_t *memory_pools_from_handler (memory_pools_handle_t memory_pools_handle) { - memory_pools_t *memory_pools; - /* Recover memory_pools */ - memory_pools = (memory_pools_t *) memory_pools_handle; - /* Sanity check on passed handle */ - AssertError (memory_pools->start_mark == POOLS_START_MARK, memory_pools = NULL, - "Handle %p is not a valid memory pools handle, start mark is missing!\n", memory_pools_handle); - return (memory_pools); -} - -static inline memory_pool_item_t *memory_pool_item_from_handler (memory_pool_item_handle_t memory_pool_item_handle) { - void *address; - memory_pool_item_t *memory_pool_item; - /* Recover memory_pools */ - address = memory_pool_item_handle - sizeof(memory_pool_item_start_t); - memory_pool_item = (memory_pool_item_t *) address; - /* Sanity check on passed handle */ - AssertError (memory_pool_item->start.start_mark == POOL_ITEM_START_MARK, memory_pool_item = NULL, - "Handle %p is not a valid memory pool item handle, start mark is missing!\n", memory_pool_item); - return (memory_pool_item); -} - -static inline memory_pool_item_t *memory_pool_item_from_index (memory_pool_t *memory_pool, items_group_index_t index) { - void *address; - address = (void *) memory_pool->items; - address += index * memory_pool->pool_item_size; - return (address); -} - -/*------------------------------------------------------------------------------*/ -memory_pools_handle_t memory_pools_create (uint32_t pools_number) { - memory_pools_t *memory_pools; - pool_id_t pool; - AssertFatal (pools_number <= MAX_POOLS_NUMBER, "Too many memory pools requested (%d/%d)!\n", pools_number, MAX_POOLS_NUMBER); /* Limit to a reasonable number of pools */ - /* Allocate memory_pools */ - memory_pools = malloc (sizeof(memory_pools_t)); - AssertFatal (memory_pools != NULL, "Memory pools structure allocation failed!\n"); - /* Initialize memory_pools */ - { - memory_pools->start_mark = POOLS_START_MARK; - memory_pools->pools_number = pools_number; - memory_pools->pools_defined = 0; - /* Allocate pools */ - memory_pools->pools = calloc (pools_number, sizeof(memory_pool_t)); - AssertFatal (memory_pools->pools != NULL, "Memory pools allocation failed!\n"); - - /* Initialize pools */ - for (pool = 0; pool < pools_number; pool++) { - memory_pools->pools[pool].start_mark = POOL_START_MARK; - } - } - return ((memory_pools_handle_t) memory_pools); -} - -char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle) { - memory_pools_t *memory_pools; - pool_id_t pool; - char *statistics; - int printed_chars; - uint32_t allocated_pool_memory; - uint32_t allocated_pools_memory = 0; - items_group_t *items_group; - uint32_t pool_items_size; - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - statistics = malloc(memory_pools->pools_defined * 200); - printed_chars = sprintf (&statistics[0], "Pool: size, number, minimum, free, address space and memory used in Kbytes\n"); - - for (pool = 0; pool < memory_pools->pools_defined; pool++) { - items_group = &memory_pools->pools[pool].items_group_free; - allocated_pool_memory = items_group_number_items (items_group) * memory_pools->pools[pool].pool_item_size; - allocated_pools_memory += allocated_pool_memory; - pool_items_size = memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t); - printed_chars += sprintf (&statistics[printed_chars], " %2u: %6u, %6u, %6u, %6u, [%p-%p] %6u\n", - pool, pool_items_size, - items_group_number_items (items_group), - items_group->minimum, - items_group_free_items (items_group), - memory_pools->pools[pool].items, - ((void *) memory_pools->pools[pool].items) + allocated_pool_memory, - allocated_pool_memory / (1024)); - } - - printed_chars = sprintf (&statistics[printed_chars], "Pools memory %u Kbytes\n", allocated_pools_memory / (1024)); - return (statistics); -} - -int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size) { - memory_pools_t *memory_pools; - memory_pool_t *memory_pool; - pool_id_t pool; - items_group_index_t item_index; - memory_pool_item_t *memory_pool_item; - AssertFatal (pool_items_number <= MAX_POOL_ITEMS_NUMBER, "Too many items for a memory pool (%u/%d)!\n", pool_items_number, MAX_POOL_ITEMS_NUMBER); /* Limit to a reasonable number of items */ - AssertFatal (pool_item_size <= MAX_POOL_ITEM_SIZE, "Item size is too big for memory pool items (%u/%d)!\n", pool_item_size, MAX_POOL_ITEM_SIZE); /* Limit to a reasonable item size */ - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - /* Check number of already created pools */ - AssertFatal (memory_pools->pools_defined < memory_pools->pools_number, "Can not allocate more memory pool (%d)!\n", memory_pools->pools_number); - /* Select pool */ - pool = memory_pools->pools_defined; - memory_pool = &memory_pools->pools[pool]; - /* Initialize pool */ - { - memory_pool->pool_id = pool; - /* Item size in memory_pool_data_t items by excess */ - memory_pool->item_data_number = (pool_item_size + sizeof(memory_pool_data_t) - 1) / sizeof(memory_pool_data_t); - memory_pool->pool_item_size = (memory_pool->item_data_number * sizeof(memory_pool_data_t)) + sizeof(memory_pool_item_t); - memory_pool->items_group_free.number_plus_one = pool_items_number + 1; - memory_pool->items_group_free.minimum = pool_items_number; - memory_pool->items_group_free.positions.ind.put = pool_items_number; - memory_pool->items_group_free.positions.ind.get = 0; - /* Allocate free indexes */ - memory_pool->items_group_free.indexes = malloc(memory_pool->items_group_free.number_plus_one * sizeof(items_group_index_t)); - AssertFatal (memory_pool->items_group_free.indexes != NULL, "Memory pool indexes allocation failed!\n"); - - /* Initialize free indexes */ - for (item_index = 0; item_index < pool_items_number; item_index++) { - memory_pool->items_group_free.indexes[item_index] = item_index; - } - - /* Last index is not allocated */ - memory_pool->items_group_free.indexes[item_index] = ITEMS_GROUP_INDEX_INVALID; - /* Allocate items */ - memory_pool->items = calloc (pool_items_number, memory_pool->pool_item_size); - AssertFatal (memory_pool->items != NULL, "Memory pool items allocation failed!\n"); - - /* Initialize items */ - for (item_index = 0; item_index < pool_items_number; item_index++) { - memory_pool_item = memory_pool_item_from_index (memory_pool, item_index); - memory_pool_item->start.start_mark = POOL_ITEM_START_MARK; - memory_pool_item->start.pool_id = pool; - memory_pool_item->start.item_status = ITEM_STATUS_FREE; - memory_pool_item->data[memory_pool->item_data_number] = POOL_ITEM_END_MARK; - } - } - memory_pools->pools_defined ++; - return (0); -} - -memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1) { - memory_pools_t *memory_pools; - memory_pool_item_t *memory_pool_item; - memory_pool_item_handle_t memory_pool_item_handle = NULL; - pool_id_t pool; - items_group_index_t item_index = ITEMS_GROUP_INDEX_INVALID; - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertError (memory_pools != NULL, {}, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - - for (pool = 0; pool < memory_pools->pools_defined; pool++) { - if ((memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t)) < item_size) { - /* This memory pool has too small items, skip it */ - continue; - } - - item_index = items_group_get_free_item(&memory_pools->pools[pool].items_group_free); - - if (item_index <= ITEMS_GROUP_INDEX_INVALID) { - /* Allocation failed, skip this pool */ - continue; - } else { - /* Allocation succeed, exit searching loop */ - break; - } - } - - if (item_index > ITEMS_GROUP_INDEX_INVALID) { - /* Convert item index into memory_pool_item address */ - memory_pool_item = memory_pool_item_from_index (&memory_pools->pools[pool], item_index); - /* Sanity check on item status, must be free */ - AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_FREE, "Item status is not set to free (%d) in pool %u, item %d!\n", - memory_pool_item->start.item_status, pool, item_index); - memory_pool_item->start.item_status = ITEM_STATUS_ALLOCATED; - memory_pool_item->start.info[0] = info_0; - memory_pool_item->start.info[1] = info_1; - memory_pool_item_handle = memory_pool_item->data; - MP_DEBUG(" Alloc [%2u][%6d]{%6d}, %3u %3u, %6u, %p, %p, %p\n", - pool, item_index, - items_group_free_items (&memory_pools->pools[pool].items_group_free), - info_0, info_1, - item_size, - memory_pools->pools[pool].items, - memory_pool_item, - memory_pool_item_handle); - } else { - MP_DEBUG(" Alloc [--][------]{------}, %3u %3u, %6u, failed!\n", info_0, info_1, item_size); - } - - return memory_pool_item_handle; -} - -int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0) { - memory_pools_t *memory_pools; - memory_pool_item_t *memory_pool_item; - pool_id_t pool; - items_group_index_t item_index; - uint32_t item_size; - uint32_t pool_item_size; - uint16_t info_1; - int result; - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertError (memory_pools != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pools for handle %p!\n", memory_pools_handle); - /* Recover memory pool item */ - memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle); - AssertError (memory_pool_item != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle); - info_1 = memory_pool_item->start.info[1]; - /* Recover pool index */ - pool = memory_pool_item->start.pool_id; - AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); - item_size = memory_pools->pools[pool].item_data_number; - pool_item_size = memory_pools->pools[pool].pool_item_size; - item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size; - MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n", - pool, item_index, - items_group_free_items (&memory_pools->pools[pool].items_group_free), - memory_pool_item->start.info[0], info_1, - memory_pool_item_handle, memory_pool_item, - memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t)))); - /* Sanity check on calculated item index */ - AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), - "Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n", - memory_pool_item,(void *)memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); - /* Sanity check on end marker, must still be present (no write overflow) */ - AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, - "Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index); - /* Sanity check on item status, must be allocated */ - AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED, - "Trying to free a non allocated (%x) memory pool item (pool %u, item %d)!\n", - memory_pool_item->start.item_status, pool, item_index); - memory_pool_item->start.item_status = ITEM_STATUS_FREE; - result = items_group_put_free_item(&memory_pools->pools[pool].items_group_free, item_index); - AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory pool item (pool %u, item %d)!\n", pool, item_index); - return (result); -} - -void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info) { - memory_pools_t *memory_pools; - memory_pool_item_t *memory_pool_item; - pool_id_t pool; - items_group_index_t item_index; - uint32_t item_size; - uint32_t pool_item_size; - AssertFatal (index < MEMORY_POOL_ITEM_INFO_NUMBER, "Incorrect info index (%d/%d)!\n", index, MEMORY_POOL_ITEM_INFO_NUMBER); - /* Recover memory pool item */ - memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle); - AssertFatal (memory_pool_item != NULL, "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle); - /* Set info[1] */ - memory_pool_item->start.info[index] = info; - - /* Check item validity and log (not mandatory) */ - if (1) { - /* Recover memory_pools */ - memory_pools = memory_pools_from_handler (memory_pools_handle); - AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle); - /* Recover pool index */ - pool = memory_pool_item->start.pool_id; - AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined); - item_size = memory_pools->pools[pool].item_data_number; - pool_item_size = memory_pools->pools[pool].pool_item_size; - item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size; - MP_DEBUG(" Info [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n", - pool, item_index, - items_group_free_items (&memory_pools->pools[pool].items_group_free), - memory_pool_item->start.info[0], memory_pool_item->start.info[1], - memory_pool_item_handle, memory_pool_item, - memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t)))); - /* Sanity check on calculated item index */ - AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index), - "Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n", - memory_pool_item, (void *)memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index); - /* Sanity check on end marker, must still be present (no write overflow) */ - AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK, - "Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index); - /* Sanity check on item status, must be allocated */ - AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED, - "Trying to free a non allocated (%x) memory pool item (pool %u, item %d)\n", - memory_pool_item->start.item_status, pool, item_index); - } -} diff --git a/common/utils/msc/msc.c b/common/utils/msc/msc.c index ae87a8e326..7cc5f79f90 100644 --- a/common/utils/msc/msc.c +++ b/common/utils/msc/msc.c @@ -88,7 +88,7 @@ void *msc_task(void *args_p) if (received_message_p != NULL) { // msg_name = ITTI_MSG_NAME (received_message_p); - // instance = ITTI_MSG_INSTANCE (received_message_p); + // instance = ITTI_MSG_DESTINATION_INSTANCE (received_message_p); switch (ITTI_MSG_ID(received_message_p)) { case TIMER_HAS_EXPIRED: { msc_flush_messages(); diff --git a/common/utils/msc/msc.h b/common/utils/msc/msc.h index 49c99abb56..aab872cfe1 100644 --- a/common/utils/msc/msc.h +++ b/common/utils/msc/msc.h @@ -48,12 +48,17 @@ typedef enum { MSC_MAC_ENB, MSC_RLC_ENB, MSC_PDCP_ENB, + MSC_PDCP_GNB, MSC_RRC_ENB, + MSC_RRC_GNB, MSC_IP_ENB, MSC_S1AP_ENB, + MSC_NGAP_GNB, MSC_GTPU_ENB, + MSC_GTPU_GNB, MSC_GTPU_SGW, MSC_S1AP_MME, + MSC_NGAP_AMF, MSC_MMEAPP_MME, MSC_NAS_MME, MSC_NAS_EMM_MME, diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index a2add514e1..8f7f48ed5a 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -16,3 +16,8 @@ #include "openair2/COMMON/gtpv1_u_messages_def.h" #include "openair2/COMMON/flexran_messages_def.h" #include "openair2/COMMON/f1ap_messages_def.h" +#include "openair2/COMMON/ngap_messages_def.h" +#if ITTI_SIM +#include "openair2/COMMON/itti_sim_messages_def.h" +#endif + diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 1680410ebb..2189be9fe8 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -30,30 +30,32 @@ extern "C" { #include #include -typedef struct timer_elm_s { - 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 -} timer_elm_t ; + typedef struct timer_elm_s { + 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 + } timer_elm_t ; -typedef struct task_list_s { - task_info_t admin; - pthread_t thread; - pthread_mutex_t queue_cond_lock; - std::vector message_queue; - std::map timer_map; - uint64_t next_timer=UINT64_MAX; - struct epoll_event *events =NULL; - int nb_fd_epoll=0; - int nb_events=0; - int epoll_fd=-1; - int sem_fd=-1; -} task_list_t; + typedef struct task_list_s { + task_info_t admin; + pthread_t thread; + pthread_mutex_t queue_cond_lock; + std::vector message_queue; + std::map timer_map; + uint64_t next_timer=UINT64_MAX; + struct epoll_event *events =NULL; + int nb_fd_epoll=0; + int nb_events=0; + int epoll_fd=-1; + int sem_fd=-1; + } task_list_t; -int timer_expired(int fd); -task_list_t tasks[TASK_MAX]; + int timer_expired(int fd); + static task_list_t **tasks=NULL; + static int nb_queues=0; + static pthread_mutex_t lock_nb_queues; void *pool_buffer_init (void) { return 0; @@ -99,7 +101,7 @@ task_list_t tasks[TASK_MAX]; // #define S1AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_register_enb_req // would become // #define S1AP_REGISTER_ENB_REQ(mSGpTR) (s1ap_register_enb_req) mSGpTR)->ittiMsg - MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, MessagesIds message_id, MessageHeaderSize size) { + MessageDef *itti_alloc_new_message_sized(task_id_t origin_task_id, instance_t originInstance, MessagesIds message_id, MessageHeaderSize size) { MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, sizeof(MessageHeader) +32 + size); temp->ittiMsgHeader.messageId = message_id; temp->ittiMsgHeader.originTaskId = origin_task_id; @@ -107,23 +109,24 @@ task_list_t tasks[TASK_MAX]; return temp; } - MessageDef *itti_alloc_new_message(task_id_t origin_task_id, MessagesIds message_id) { + MessageDef *itti_alloc_new_message(task_id_t origin_task_id, instance_t originInstance, MessagesIds message_id) { int size=sizeof(MessageHeader) + 32 + messages_info[message_id].size; MessageDef *temp = (MessageDef *)itti_malloc (origin_task_id, TASK_UNKNOWN, size); temp->ittiMsgHeader.messageId = message_id; temp->ittiMsgHeader.originTaskId = origin_task_id; temp->ittiMsgHeader.ittiMsgSize = size; temp->ittiMsgHeader.destinationTaskId=TASK_UNKNOWN; - temp->ittiMsgHeader.instance=0; - temp->ittiMsgHeader.lte_time={0}; + temp->ittiMsgHeader.originInstance=originInstance; + temp->ittiMsgHeader.destinationInstance=0; + temp->ittiMsgHeader.lte_time= {0}; return temp; //return itti_alloc_new_message_sized(origin_task_id, message_id, messages_info[message_id].size); } - static inline int itti_send_msg_to_task_locked(task_id_t destination_task_id, instance_t instance, MessageDef *message) { - task_list_t *t=tasks+destination_task_id; + static inline int itti_send_msg_to_task_locked(task_id_t destination_task_id, instance_t destinationInstance, MessageDef *message) { + task_list_t *t=tasks[destination_task_id]; message->ittiMsgHeader.destinationTaskId = destination_task_id; - message->ittiMsgHeader.instance = instance; + message->ittiMsgHeader.destinationInstance = destinationInstance; message->ittiMsgHeader.lte_time.frame = 0; message->ittiMsgHeader.lte_time.slot = 0; int message_id = message->ittiMsgHeader.messageId; @@ -142,25 +145,27 @@ task_list_t tasks[TASK_MAX]; return 0; } - int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) { - task_list_t *t=&tasks[destination_task_id]; + int itti_send_msg_to_task(task_id_t destination_task_id, instance_t destinationInstance, MessageDef *message) { + task_list_t *t=tasks[destination_task_id]; pthread_mutex_lock (&t->queue_cond_lock); - int ret=itti_send_msg_to_task_locked(destination_task_id, instance, message); + int ret=itti_send_msg_to_task_locked(destination_task_id, destinationInstance, message); while ( t->message_queue.size()>0 && t->admin.func != NULL ) { if (t->message_queue.size()>1) - LOG_W(TMR,"queue in no thread mode is %ld\n", t->message_queue.size()); + LOG_W(TMR,"queue in no thread mode is %ld\n", t->message_queue.size()); + pthread_mutex_unlock (&t->queue_cond_lock); t->admin.func(NULL); pthread_mutex_lock (&t->queue_cond_lock); } + pthread_mutex_unlock (&t->queue_cond_lock); return ret; } void itti_subscribe_event_fd(task_id_t task_id, int fd) { struct epoll_event event; - task_list_t *t=&tasks[task_id]; + task_list_t *t=tasks[task_id]; t->nb_fd_epoll++; t->events = (struct epoll_event *)realloc((void *)t->events, t->nb_fd_epoll * sizeof(struct epoll_event)); @@ -173,7 +178,7 @@ task_list_t tasks[TASK_MAX]; } void itti_unsubscribe_event_fd(task_id_t task_id, int fd) { - task_list_t *t=&tasks[task_id]; + task_list_t *t=tasks[task_id]; AssertFatal (epoll_ctl(t->epoll_fd, EPOLL_CTL_DEL, fd, NULL) == 0, "epoll_ctl (EPOLL_CTL_DEL) failed for task %s, fd %d: %s!\n", itti_get_task_name(task_id), fd, strerror(errno)); @@ -181,7 +186,7 @@ task_list_t tasks[TASK_MAX]; } static inline int itti_get_events_locked(task_id_t task_id, struct epoll_event **events) { - task_list_t *t=&tasks[task_id]; + task_list_t *t=tasks[task_id]; uint64_t current_time=0; do { @@ -194,9 +199,11 @@ task_list_t tasks[TASK_MAX]; t->next_timer=UINT64_MAX; // Proceed expired timer - for ( auto it=t->timer_map.begin() ; it != t->timer_map.end() ; ++it ) { + for ( auto it=t->timer_map.begin(), next_it = it; it != t->timer_map.end() ; it = next_it ) { + ++next_it; + if ( it->second.timeout < current_time ) { - MessageDef *message = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED); + MessageDef *message = itti_alloc_new_message(TASK_TIMER, it->second.instance,TIMER_HAS_EXPIRED); message->ittiMsg.timer_has_expired.timer_id=it->first; message->ittiMsg.timer_has_expired.arg=it->second.timer_arg; @@ -228,8 +235,9 @@ task_list_t tasks[TASK_MAX]; pthread_mutex_unlock(&t->queue_cond_lock); LOG_D(TMR,"enter blocking wait for %s\n", itti_get_task_name(task_id)); t->nb_events = epoll_wait(t->epoll_fd,t->events,t->nb_fd_epoll, epoll_timeout); + if ( t->nb_events < 0 && (errno == EINTR || errno == EAGAIN ) ) - pthread_mutex_lock(&t->queue_cond_lock); + pthread_mutex_lock(&t->queue_cond_lock); } while (t->nb_events < 0 && (errno == EINTR || errno == EAGAIN ) ); AssertFatal (t->nb_events >=0, @@ -258,13 +266,13 @@ task_list_t tasks[TASK_MAX]; } int itti_get_events(task_id_t task_id, struct epoll_event **events) { - pthread_mutex_lock(&tasks[task_id].queue_cond_lock); + pthread_mutex_lock(&tasks[task_id]->queue_cond_lock); return itti_get_events_locked(task_id, events); } void itti_receive_msg(task_id_t task_id, MessageDef **received_msg) { // Reception of one message, blocking caller - task_list_t *t=&tasks[task_id]; + task_list_t *t=tasks[task_id]; pthread_mutex_lock(&t->queue_cond_lock); // Weird condition to deal with crap legacy itti interface @@ -294,10 +302,9 @@ task_list_t tasks[TASK_MAX]; pthread_mutex_unlock (&t->queue_cond_lock); } - void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) - { + void itti_poll_msg(task_id_t task_id, MessageDef **received_msg) { //reception of one message, non-blocking - task_list_t *t=&tasks[task_id]; + task_list_t *t=tasks[task_id]; pthread_mutex_lock(&t->queue_cond_lock); if (!t->message_queue.empty()) { @@ -311,11 +318,10 @@ task_list_t tasks[TASK_MAX]; } int itti_create_task(task_id_t task_id, - void *(*start_routine)(void *), - void *args_p) - { - task_list_t *t=&tasks[task_id]; - threadCreate (&t->thread, start_routine, args_p, (char*)itti_get_task_name(task_id),-1,OAI_PRIORITY_RT); + void *(*start_routine)(void *), + void *args_p) { + task_list_t *t=tasks[task_id]; + threadCreate (&t->thread, start_routine, args_p, (char *)itti_get_task_name(task_id),-1,OAI_PRIORITY_RT); LOG_I(TMR,"Created Posix thread %s\n", itti_get_task_name(task_id) ); return 0; } @@ -324,31 +330,39 @@ task_list_t tasks[TASK_MAX]; pthread_exit (NULL); } - void itti_terminate_tasks(task_id_t task_id) - { + void itti_terminate_tasks(task_id_t task_id) { // Sends Terminate signals to all tasks. itti_send_terminate_message (task_id); usleep(100*1000); // Allow the tasks to receive the message before going returning to main thread } + int itti_create_queue(const task_info_t *taskInfo) { + pthread_mutex_lock (&lock_nb_queues); + int newQueue=nb_queues++; + AssertFatal(tasks=(task_list_t **) realloc(tasks, nb_queues * sizeof(*tasks)),""); + tasks[newQueue]= new task_list_t; + pthread_mutex_unlock (&lock_nb_queues); + LOG_I(TMR,"Starting itti queue: %s as task %d\n", taskInfo->name, newQueue); + pthread_mutex_init(&tasks[newQueue]->queue_cond_lock, NULL); + memcpy(&tasks[newQueue]->admin, taskInfo, sizeof(task_info_t)); + AssertFatal( ( tasks[newQueue]->epoll_fd = epoll_create1(0) ) >=0, ""); + AssertFatal( ( tasks[newQueue]->sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, ""); + itti_subscribe_event_fd((task_id_t)newQueue, tasks[newQueue]->sem_fd); + + if (tasks[newQueue]->admin.threadFunc != NULL) + itti_create_task((task_id_t)newQueue, tasks[newQueue]->admin.threadFunc, NULL); + + return newQueue; + } + int itti_init(task_id_t task_max, - thread_id_t thread_max, - MessagesIds messages_id_max, - const task_info_t *tasks_info, - const message_info_t *messages_info) - { - AssertFatal(TASK_MAX=0, ""); - AssertFatal( ( tasks[i].sem_fd = eventfd(0, EFD_SEMAPHORE) ) >=0, ""); - itti_subscribe_event_fd((task_id_t)i, tasks[i].sem_fd); - - if (tasks[i].admin.threadFunc != NULL) - itti_create_task((task_id_t)i, tasks[i].admin.threadFunc, NULL); + itti_create_queue(&tasks[i]); } return 0; @@ -358,12 +372,11 @@ task_list_t tasks[TASK_MAX]; uint32_t interval_sec, uint32_t interval_us, task_id_t task_id, - int32_t instance, + instance_t instance, timer_type_t type, void *timer_arg, - long *timer_id) - { - task_list_t *t=&tasks[task_id]; + long *timer_id) { + task_list_t *t=tasks[task_id]; do { // set the taskid in the timer id to keep compatible with the legacy API @@ -396,13 +409,12 @@ task_list_t tasks[TASK_MAX]; return 0; } - int timer_remove(long timer_id) - { + int timer_remove(long timer_id) { task_id_t task_id=(task_id_t)(timer_id&0xffff); int ret; - pthread_mutex_lock (&tasks[task_id].queue_cond_lock); - ret=tasks[task_id].timer_map.erase(timer_id); - pthread_mutex_unlock (&tasks[task_id].queue_cond_lock); + pthread_mutex_lock (&tasks[task_id]->queue_cond_lock); + ret=tasks[task_id]->timer_map.erase(timer_id); + pthread_mutex_unlock (&tasks[task_id]->queue_cond_lock); if (ret==1) return 0; @@ -417,7 +429,7 @@ task_list_t tasks[TASK_MAX]; } const char *itti_get_task_name(task_id_t task_id) { - return tasks[task_id].admin.name; + return tasks[task_id]->admin.name; } // void for compatibility @@ -438,5 +450,7 @@ task_list_t tasks[TASK_MAX]; void itti_wait_ready(int wait_tasks) { // Stupid function, kept for compatibility (the parameter is meaningless!!!) } - int signal_mask(void) { return 0;} + int signal_mask(void) { + return 0; + } } diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 026c8270d7..18a8f7868c 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -45,7 +45,7 @@ typedef struct { uint32_t interval_sec; uint32_t interval_us; long task_id; - int32_t instance; + instance_t instance; timer_type_t type; void *timer_arg; long timer_id; @@ -230,6 +230,7 @@ typedef struct IttiMsgText_s { #include #include #include +#include #include #include #include @@ -259,7 +260,11 @@ typedef struct IttiMsgText_s { #include void *rrc_enb_process_itti_msg(void *); #include -#include +#include + +#ifdef ITTI_SIM + #include +#endif /* static const char *const messages_definition_xml = { @@ -295,7 +300,7 @@ typedef struct { //TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) //TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000,NULL, NULL) //TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL) -void * rrc_enb_process_msg(void*); +void *rrc_enb_process_msg(void *); #define FOREACH_TASK(TASK_DEF) \ TASK_DEF(TASK_UNKNOWN, TASK_PRIORITY_MED, 50, NULL, NULL) \ TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10, NULL, NULL) \ @@ -312,6 +317,7 @@ void * rrc_enb_process_msg(void*); TASK_DEF(TASK_RRC_GNB, TASK_PRIORITY_MED, 200, NULL,NULL)\ TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_NGAP, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \ @@ -329,6 +335,7 @@ void * rrc_enb_process_msg(void*); TASK_DEF(TASK_RLC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PDCP_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200, NULL, NULL)\ @@ -336,6 +343,8 @@ void * rrc_enb_process_msg(void*); TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 1000, NULL, NULL)\ TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL) #define TASK_DEF(TaskID, pRIO, qUEUEsIZE, FuNc, ThreadFunc) { pRIO, qUEUEsIZE, #TaskID, FuNc, ThreadFunc }, @@ -393,7 +402,8 @@ typedef struct MessageHeader_s { MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */ task_id_t originTaskId; /**< ID of the sender task */ task_id_t destinationTaskId; /**< ID of the destination task */ - instance_t instance; /**< Task instance for virtualization */ + instance_t originInstance; + instance_t destinationInstance; itti_lte_time_t lte_time; MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */ } MessageHeader; @@ -423,11 +433,11 @@ typedef struct MessageDef_s { /* Extract the instance from a message */ -#define ITTI_MESSAGE_GET_INSTANCE(mESSAGE) ((mESSAGE)->ittiMsgHeader.instance) #define ITTI_MSG_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.messageId) #define ITTI_MSG_ORIGIN_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.originTaskId) #define ITTI_MSG_DESTINATION_ID(mSGpTR) ((mSGpTR)->ittiMsgHeader.destinationTaskId) -#define ITTI_MSG_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.instance) +#define ITTI_MSG_ORIGIN_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.originInstance) +#define ITTI_MSG_DESTINATION_INSTANCE(mSGpTR) ((mSGpTR)->ittiMsgHeader.destinationInstance) #define ITTI_MSG_NAME(mSGpTR) itti_get_message_name(ITTI_MSG_ID(mSGpTR)) #define ITTI_MSG_ORIGIN_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_ORIGIN_ID(mSGpTR)) #define ITTI_MSG_DESTINATION_NAME(mSGpTR) itti_get_task_name(ITTI_MSG_DESTINATION_ID(mSGpTR)) @@ -490,6 +500,8 @@ int itti_create_task(task_id_t task_id, void *(*start_routine) (void *), void *args_p); +int itti_create_queue(const task_info_t *task_info); + /** \brief Exit the current task. **/ void itti_exit_task(void); @@ -520,6 +532,7 @@ const char *itti_get_task_name(task_id_t task_id); **/ MessageDef *itti_alloc_new_message( task_id_t origin_task_id, + instance_t originInstance, MessagesIds message_id); /** \brief Alloc and memset(0) a new itti message. @@ -530,6 +543,7 @@ MessageDef *itti_alloc_new_message( **/ MessageDef *itti_alloc_new_message_sized( task_id_t origin_task_id, + instance_t originInstance, MessagesIds message_id, MessageHeaderSize size); @@ -537,7 +551,7 @@ MessageDef *itti_alloc_new_message_sized( This function should be called from the main thread after having created all ITTI tasks. **/ void itti_wait_tasks_end(void); -#define THREAD_MAX 0 //for compatibility +#define ADDED_QUEUES_MAX 10 // Fix me: MSC component too hard to understand, we keep room for 10 queues created dynamically void itti_set_task_real_time(task_id_t task_id); /** \brief Send a termination message to all tasks. @@ -551,13 +565,12 @@ void *malloc_or_fail(size_t size); int memory_read(const char *datafile, void *data, size_t size); int itti_free(task_id_t task_id, void *ptr); -int itti_init(task_id_t task_max, thread_id_t thread_max, MessagesIds messages_id_max, const task_info_t *tasks_info, - const message_info_t *messages_info); +int itti_init(task_id_t task_max, const task_info_t *tasks_info); int timer_setup( uint32_t interval_sec, uint32_t interval_us, task_id_t task_id, - int32_t instance, + instance_t instance, timer_type_t type, void *timer_arg, long *timer_id); diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 9dd512091d..6a0da678e2 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -121,9 +121,11 @@ char toksep[2]; case SCHED_RR: lptr+=sprintf(lptr,"%s ","rt: rr"); break; +#ifdef SCHED_DEADLINE case SCHED_DEADLINE: lptr+=sprintf(lptr,"%s ","rt: deadline"); break; +#endif default: lptr+=sprintf(lptr,"%s ","????"); break; diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index e1446f15d7..77729ae7a7 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -92,7 +92,7 @@ void *one_thread(void *arg) { } while (true); } -void initTpool(char *params,tpool_t *pool, bool performanceMeas) { +void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name) { memset(pool,0,sizeof(*pool)); char *measr=getenv("threadPoolMeasurements"); pool->measurePerf=performanceMeas; @@ -116,6 +116,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->restrictRNTI=false; curptr=strtok_r(parms_cpy,",",&saveptr); struct one_thread * ptr; + char *tname = (name == NULL ? "Tpool" : name); while ( curptr!=NULL ) { int c=toupper(curptr[0]); @@ -129,7 +130,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { break; default: - ptr=pool->allthreads; + ptr=pool->allthreads; pool->allthreads=(struct one_thread *)malloc(sizeof(struct one_thread)); pool->allthreads->next=ptr; printf("create a thread for core %d\n", atoi(curptr)); @@ -138,7 +139,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->allthreads->pool=pool; //Configure the thread scheduler policy for Linux // set the thread name for debugging - sprintf(pool->allthreads->name,"Tpool_%d",pool->allthreads->coreID); + sprintf(pool->allthreads->name,"%s%d_%d",tname,pool->nbThreads,pool->allthreads->coreID); threadCreate(&pool->allthreads->threadID, one_thread, (void *)pool->allthreads, pool->allthreads->name, pool->allthreads->coreID, OAI_PRIORITY_RT); pool->nbThreads++; diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h index 0ed8715811..5db1a5e34e 100644 --- a/common/utils/threadPool/thread-pool.h +++ b/common/utils/threadPool/thread-pool.h @@ -45,7 +45,7 @@ #define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,""); #define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); #define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,""); - +#define tpool_nbthreads(tpool) (tpool.nbThreads) typedef struct notifiedFIFO_elt_s { struct notifiedFIFO_elt_s *next; uint64_t key; //To filter out elements @@ -294,6 +294,6 @@ static inline int abortTpool(tpool_t *t, uint64_t key) { mutexunlock(nf->lockF); return nbRemoved; } -void initTpool(char *params,tpool_t *pool, bool performanceMeas); - +void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name); +#define initTpool(PARAMPTR,TPOOLPTR, MEASURFLAG) initNamedTpool(PARAMPTR,TPOOLPTR, MEASURFLAG, NULL) #endif diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md index bc1b1db54a..a087b989fa 100644 --- a/common/utils/threadPool/thread-pool.md +++ b/common/utils/threadPool/thread-pool.md @@ -6,10 +6,9 @@ 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: @@ -18,65 +17,191 @@ When a job is done, the worker sends a return if a return is defined. # 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): - The job messages can be created with newNotifiedFIFO_elt() and delNotifiedFIFO_elt() or managed by the client. +* 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. # 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: - push_notifiedFIFO() add a job in the queue - pull_notifiedFIFO() is blocking, poll_notifiedFIFO() is non blocking +* 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 +* 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) +These queues details hereafter + +## Common + +newNotifiedFIFO_elt() + +creates a message, that will later be used in queues/FIFO + +delNotifiedFIFO_elt() + +deletes it + +NotifiedFifoData() + +gives a pointer to the beginning of free usage memory in a message (you can put any data there, up to 'size' parameter you passed to newNotifiedFIFO_elt() + +These 3 calls are not mandatory, you can also use your own memory to save the malloc()/free() that are behind these calls +iFirst level: non thread safe FIFO (or queues) + +# low level: fast and simple + +initNotifiedFIFO_nothreadSafe() + +to create a queue + +pushNotifiedFIFO_nothreadSafe() + +Add a element in a queue + +pullNotifiedFIFO_nothreadSafe() + +pull a element from a queue + +As these queues are not thread safe, there is NO blocking mechanism, neither pull() versus poll() calls + +There is no delete for a message queue: you only have to abandon the memory you allocated to call iinitNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf) + +So if you malloced the memory under 'nf' parameter you have to free it, if it is automatic variable (local variable) or global variable, nothing is to be done. + + +## thread safe queues + +These queues are built on not thread safe queues when we need thread to thread protection + +initNotifiedFIFO() + +to create a queue + +pushNotifiedFIFO() + +Add a element in a queue + +pullNotifiedFIFO() + +pull a element from a queue, this call is blocking until a message arrived + +pollNotifiedFIFO() + +pull a element from a queue, this call is not blocking, so it returns always very shortly + +in 99.9% cases, pull() is better than poll() + +No delete() call, same principle as not thread safe queues # 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 `initTpool(char *params,tpool_t *pool, bool performanceMeas )` or `initNamedTpool(char *params,tpool_t *pool, bool performanceMeas , char *name)` - 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 params string structure: describes a list of cores, separated by "," that run a worker thread - The threads are all Linux real time scheduler, their name is set automatically is "Tpool_" +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 to `Tpool_` if initTpool is used or to `_` when initNamedTpool is used. ## 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. + +## API details +Each thread pool (there can be several in the same process) should be initialized once using one of the two API's: + +### initNamedTpool(char *params,tpool_t *pool, bool performanceMeas,char *name) + +### initTpool(char *params,tpool_t *pool, bool performanceMeas) + +`params`: the configuration parameter is a string, elements separator is a comma ",". An element can be: + +* N: if a N is in the parameter list, no threads are created + The purpose is to keep the same API in any case +* a CPU with a little number of cores, + or in debugging sessions to simplify the human work +* a number that represent a valid CPU core on the target CPU + A thread is created and stick on the core (with set affinity) +* a number that is not a valid CPU core + a floating thread is created (Linux is responsible of the real time core allocation) + +example: "-1,-1,-1" +as there is no core number -1, the thread pool is made of 3 floating threads +be careful with fix allocation: it is hard to be more clever than Linux kernel + +`pool` is the memory you allocated before to store the thread pool internal state (same concept as above queues) + +`performanceMeas` is a flag to enable measurements (well described in documentation) + +`name` is used to build the thread names. + +### pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) + +adds a job to do in the thread pool + +The msg data you can set are: + +* key: + a value for you that you will find back in the response + it is also the key for abortTpool() +* reponseFifo + if you set it, the message will be sent back on this queue when the job is done + if you don't set it, no return is performed, the thread pool frees the message 'msg' when the job is done +* processingFunc + the function the job will run. the function prototype is void (void *memory) + the data part (the pointer returned by NotifiedFifoData(msg)) is passed to the function + it is used to send data to the processing function and also to write back results + of course, writing back results will lead you to use also a return queue (the parameter reponseFifo) + +### pullTpool() collects job result in a return queue + +you collect results in one result queue: the message you gave to pushTpool(), nevertheless it has been updated by processingFunc() + +An example of multiple return queues, in eNB: I created one single thread pool (because it depends mainly on CPU hardware), but i use two return queues: one for turbo encode, one for turbo decode. + +### tryPullTpool() + +is the same, but not blocking (pollTpool() would have been a better name) + +### abortTpool() + +Is a facility to cancel work you pushed to a thread pool + +I used it once: when eNB performs turbo decode, I push all segments in the thread pool. + +But when I get back the decoding results, if one segment can't be decoded, I don't need the results of the other segments of the same UE. ## Performance measurements - A performance measurement is integrated: - the pool will automacillay fill timestamps: - - * creationTime: - time the request is push to the pool; +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: diff --git a/doc/5Gnas.md b/doc/5Gnas.md new file mode 100644 index 0000000000..3d33af426c --- /dev/null +++ b/doc/5Gnas.md @@ -0,0 +1,107 @@ + + + +This tuto for 5G gNB NAS design +{: .text-center} + +# source files + +executables/ocp-gnb.c: a main loop to create a debuggable gNB, see document SW_archi.md +openair2/RRC/NR/nr_ngap_gNB.c: skeleton for interface with NGAP +openair3/NAS/COMMON/milenage.h: a simple milenage implementation, depend only on crypto library +openair3/NAS/COMMON/NR_NAS_defs.h: messages defined for NAS implemented in C: C struct, C enums and automatic conversion to labels for debug messages +openair3/NAS/COMMON/nr_common.c: 5G NAS common code between gNB and UE +openair3/UICC/usim_interface.c: UICC simulation for USIM messages + +openair3/NAS/NR_UE/ue_process_nas.c: NAS code for UE + +openair3/NAS/gNB/network_process_nas.c: NAS code for gNB running without 5GC + +openair3/TEST/test5Gnas.c: unitary testing of NAS messages: encodes+decode a standard network entry, mixing code from UE and 5GC (or gNB in noCore) + +# USIM simulation +A new USIM simulation, that parameters are in regular OAI config files + +## To open the USIM +init_uicc() takes a parameter: the name of the block in the config file +In case we run several UEs in one process, the variable section name allows to make several UEs configurations in one config file. + +The NAS implementation uses this possibility. + +# UE side +UEprocessNAS() is the entry for all messages. +It decodes the message type and call the specific function for each messgae + +## Identityrequest + IdentityResponse +When the UE receives the request, it stores the 5GC request parameters in the UE context ( UE->uicc pointer) +It calls "scheduleNAS", that would trigger a answer (seeing general archtecture, it will probly be a itti message to future RRC or NGAP thread). + +When the scheduler wants to encode the answer, it calls identityResponse() +The UE search for a section in the config file called "uicc" +it encodes the NAS answer with the IMSI, as a 4G compatible authentication. +A future release would encode 5G SUPI as native 5G UICC. + +## Authenticationrequest + authenticationResponse +When the UE receives the request, it stores the 5GC request parameters in the UE context ( UE->uicc pointer) +It calls "scheduleNAS", that would trigger a answer (seeing general archtecture, it will probly be a itti message to future RRC or NGAP thread). + +When the scheduler wants to encode the answer, it calls authenticationResponse() +The UE search for a section in the config file called "uicc" +It uses the Milenage parameters of this section to encode a milenage response +A future release would encode 5G new authentication cyphering functions. + +## SecurityModeCommand + securityModeComplete +When the UE receives the request it will: +Selected NAS security algorithms: store it for future encoding +Replayed UE security capabilities: check if it is equal to UE capabilities it sent to the 5GC +IMEISV request: to implement +ngKSI: Key set Indicator, similator to 4G to select a ciphering keys set + +When the scheduler wants to encode the answer, it calls registrationComplete() + +## registrationComplete +To be defined in UE, this NAS message is done after RRC sequence completes + +# gNB side +gNB NGAP thread receives the NAS message from PHY layers +In normal mode, it send it to the core network with no decoding. + +Here after, the gNB mode "noCore" processing in gNB: NGAP calls the entry function: processNAS() instead of forwarding the packet to the 5GC + +## RRCModeComplete + Identityrequest +When the gNB completes RRC attach, it sends a first message to NGAP thread. +Normal processing sends NGAP initial UE message, in noCore mode, it should call: identityRequest() that encode the NAS identity request inside the gNB. +The gNB NGAP thread then should call the piece of code that forward the message to the UE as when it receives a NAS message from 5GC. + +## All NAS coming from UE +When NGAP thread receives a NAS message from lower layers, it encapsulates it to forward it to the 5GC. In "noCore" mode it calls processNAS(). + +This function stores in the gNB the NAS data, then it should encode the next message (identity, authentication, security mode) or do nothing (registration complete). + + +
+**Note** +{: .panel-heading} +
+ + +
+
+ diff --git a/doc/BASIC_SIM.md b/doc/BASIC_SIM.md index ab4c3489d9..1bfc6e76d2 100644 --- a/doc/BASIC_SIM.md +++ b/doc/BASIC_SIM.md @@ -27,7 +27,7 @@ $ cd cmake_targets $ ./build_oai --eNB --UE ``` -Both eNB (lte-softmodem) and UE (lte-uesoftmodem) are present on `cmake_targets/lte_build_oai/build` folder. +Both eNB (lte-softmodem) and UE (lte-uesoftmodem) are present on `cmake_targets/ran_build/build` folder. More details are available on the [build page](BUILD.md). @@ -50,7 +50,7 @@ Example 1: running in FDD mode with EPC. ```bash $ source oaienv -$ cd cmake_targets/lte_build_oai/build +$ cd cmake_targets/ran_build/build $ ENODEB=1 sudo -E ./lte-softmodem -O $OPENAIR_HOME/ci-scripts/conf_files/lte-fdd-basic-sim.conf --basicsim ``` @@ -64,7 +64,7 @@ Example 2: running in TDD mode without any EPC. ```bash $ source oaienv -$ cd cmake_targets/lte_build_oai/build +$ cd cmake_targets/ran_build/build $ ENODEB=1 sudo -E ./lte-softmodem -O $OPENAIR_HOME/ci-scripts/conf_files/lte-tdd-basic-sim.conf --basicsim --noS1 ``` @@ -79,7 +79,7 @@ You need to set the correct OPC, USIM_API_K, MSIN (this is the end par of the IM ```bash $ source oaienv # Edit openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -$ cd cmake_targets/lte_build_oai/build +$ cd cmake_targets/ran_build/build $ ../../nas_sim_tools/build/conf2uedata -c $OPENAIR_HOME/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o . $ sudo -E ./lte-uesoftmodem -C 2625000000 -r 25 --ue-rxgain 140 --basicsim [--noS1] ``` diff --git a/doc/BUILD.md b/doc/BUILD.md index ba5db55cab..bbb06a1e69 100644 --- a/doc/BUILD.md +++ b/doc/BUILD.md @@ -51,6 +51,19 @@ Calling the `build_oai` script with the -h option gives the list of all availabl # Building PHY Simulators +The PHY layer simulators (LTE and NR) can be built as follows: + +``` +cd /openairinterface5g/ +source oaienv +cd cmake_targets/ +./build_oai -I --phy_simulators +``` + +After completing the build, the binaries are available in the cmake_targets/phy_simulators/build directory. +A copy is also available in the target/bin directory, with all binaries suffixed by the 3GPP release number, today **.Rel15**. + + Detailed information about these simulators can be found [in this dedicated page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/OpenAirLTEPhySimul) # Building UEs, eNodeB and gNodeB Executables diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 23d32effbb..2171fc2f1f 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -254,14 +254,17 @@ The NAS layer is based on **3GPP 24.301** and implements the following functions The following features are valid for the gNB and the 5G-NR UE. * Static TDD, +* FDD * Normal CP * 30 kHz subcarrier spacing * Bandwidths up to 80MHz (217 Physical Resource Blocks) +* Intermediate downlink and uplink frequencies to interface with IF equipment * Single antenna port (single beam) * Slot format: 14 OFDM symbols in UL or DL * Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported) * Highly efficient 3GPP compliant polar encoder and decoder * Encoder and decoder for short blocks +* Support for UL transform precoding (SC-FDMA) ## gNB PHY Layer ## @@ -293,6 +296,7 @@ The following features are valid for the gNB and the 5G-NR UE. - NR RRC (38.331) Rel 15 messages using new asn1c - LTE RRC (36.331) also updated to Rel 15 - Generation of CellGroupConfig (for eNB) and MIB +- Generation of system information block 1 (SIB1) - Application to read configuration file and program gNB RRC - RRC can configure PDCP, RLC, MAC @@ -303,7 +307,8 @@ The following features are valid for the gNB and the 5G-NR UE. **gNB MAC** - MAC -> PHY configuration using NR FAPI P5 interface - MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU -- Scheduler for RA procedreat gNB +- Scheduler procedures for SIB1 +- Scheduler procedures for RA - MAC downlink scheduler (fixed allocations) - MAC header generation (including timing advance) - ACK / NACK handling and HARQ procedures for downlink @@ -348,11 +353,13 @@ The following features are valid for the gNB and the 5G-NR UE. ## UE Higher Layers ## -**gNB MAC** -- Initial sync and MIB detection -- MAC -> PHY configuration of PHY via UE FAPI P5 interface -- Basic MAC to control PHY via UE FAPI P7 interface -- Random access procedure +**UE MAC** +* Minimum system information (MSI) + - Initial sync and MIB detection + - System information block 1 (SIB1) reception +* MAC -> PHY configuration of PHY via UE FAPI P5 interface +* Basic MAC to control PHY via UE FAPI P7 interface +* Random access procedure **RLC** diff --git a/doc/ITTISIM.md b/doc/ITTISIM.md new file mode 100755 index 0000000000..13fdd90846 --- /dev/null +++ b/doc/ITTISIM.md @@ -0,0 +1,48 @@ + + + + + +
+ + + + + + Running L3 ITTI simulator +
+ +This page is valid on the following branches: + +- `develop` starting from tag `2020.w48` + +# 1. Building the ITTI simulator. + +The ITTI simulator is available directly from the standard build. + +```bash +$ source oaienv +$ cd cmake_targets +$ sudo ./build_oai -x -w None -c -ittiSIM +``` + +# 2. Running the ITTI simulator. + +The ITTI simulator establishes ITTI-threaded communication between the gNB RRC task and the UE RRC task. + +This allows to test the sequence of NGAP/RRC/NAS messages. + +The main limitations are: + +- NAS is a simple stub that just sends and receives messages +- only initial Attach sequence + +## 2.1. Starting the ITTI simulator + +The ITTI simulator is able to run with a connected 5GC or without any. +The develop branch tag `2020.w48` only works RRC without 5GC connection. + +```bash +$ sudo -E ./ran_build/build/nr-ittisim -O gnb.conf +``` + diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 5fb0824565..d13b193ff9 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -132,6 +132,76 @@ With the RF simulator (on the same machine): `sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD` +## sa setup with OAI + +The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1. + +In order to run gNB in standalone mode, the following flag is needed at gNB: + +`--sa` + +### Run OAI in sa mode + +At the gNB the --sa flag does the following +- it reads the RRC configuration from the configuration file +- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw +- the RRC encodes SIB1 according the configuration file and transmits it through PDSCH + +At the UE the --sa flag will +- read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them. + +From the `cmake_targets/ran_build/build` folder: + +gNB on machine 1: + +`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --sa` + +UE on machine 2: + +`sudo ./nr-uesoftmodem --rrc_config_path . --sa` + +With the RF simulator (on the same machine): + +`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --rfsim --sa` + +`sudo ./nr-uesoftmodem --rrc_config_path . --rfsim --sa` + +## IF setup with OAI + +The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment. + +In order to run this setup, the following flags are needed at the UE side: + +`-C` + +`--CO` + +and the following parameters must be configured in the RUs section of the gNB configuration file: + +`if_freq` + +`if_offset` + +### Run OAI with custom DL/UL intermediate frequencies + +The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 at gNB side. + +From the `cmake_targets/ran_build/build` folder: + +gNB on machine 1: + +`sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf` + +UE on machine 2: + +`sudo ./nr-uesoftmodem -C 2169080000 --CO -400000000` + + + + + + + [oai wiki home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/doc/SW_archi.md b/doc/SW_archi.md new file mode 100644 index 0000000000..d92f802148 --- /dev/null +++ b/doc/SW_archi.md @@ -0,0 +1,312 @@ + + + +This tuto for 5G gNB design, with Open Cells main +{: .text-center} + +# Top file: executables/ocp-gnb.c + +the function main() initializes the data from configuration file + +# The main thread is in ru_thread() +The infinite loop: +## rx_rf() + Collect radio signal samples from RF board + all SDR processing is triggered by I/Q sample reception and it's date (timestamp) + TX I/Q samples will have a date in the future, compared to RX timestamp + called for each 5G NR slot + it blocks until data is available + the internal time comes from the RF board sampling numbers + (each sample has a incremental number representing a very accurate timing) +raw incoming data is in buffer called "rxdata" + We derivate frame number, slot number, ... from the RX timestamp +{: .func2} +## nr_fep_full() +"front end processing" of uplink signal +performs DFT on the signal +same function (duplicates): phy_procedures_gNB_common_RX() +it computes the buffer rxdataF (for frequency) from rxdata (samples over time) +rxdataF is the rxdata in frequency domain, phase aligned +{: .func3} +## gNB_top() +only compute frame numbre, slot number, ... +{: .func3} +## ocp_rxtx() +main processing for both UL and DL +start by calling oai_subframe_ind() that trigger processing in pnf_p7_subframe_ind() purpose ??? +all the context is in the passed structure UL_INFO +the context is not very clear: there is a mutex on it, +but not actual coherency (see below handle_nr_rach() assumes data is up-to-date) +The first part (in NR_UL_indication, uses the data computed by the lower part (phy_procedures_gNB_uespec_RX), but for the **previous** slot +Then, phy_procedures_gNB_uespec_RX will hereafter replace the data for the next run +This is very tricky and not thread safe at all. +{: .func3} + +### NR_UL_indication() +This block processes data already decoded and stored in structures behind UL_INFO +{: .func4} + +* handle_nr_rach() +process data from RACH primary detection +if the input is a UE RACH detection +{: .func4} + * nr_schedule_msg2() +{: .func4} +* handle_nr_uci() +handles uplink control information, i.e., for the moment HARQ feedback. +{: .func4} +* handle_nr_ulsch() +handles ulsch data prepared by nr_fill_indication() +{: .func4} +* gNB_dlsch_ulsch_scheduler () +the **scheduler** is called here, see dedicated chapter +{: .func4} +* NR_Schedule_response() +process as per the scheduler decided +{: .func4} + +### L1_nr_prach_procedures() +???? +{: .func4} +### phy_procedures_gNB_uespec_RX() +* nr_decode_pucch0() +actual CCH channel decoding form rxdataF (rx data in frequency domain) +populates UL_INFO.uci_ind, actual uci data is in gNB->pucch +{: .func4} +* nr_rx_pusch() +{: .func4} + * extracts data from rxdataF (frequency transformed received data) +{: .func4} + * nr_pusch_channel_estimation() +{: .func4} + * nr_ulsch_extract_rbs_single() +{: .func4} + * nr_ulsch_scale_channel() +{: .func4} + * nr_ulsch_channel_level() +{: .func4} + * nr_ulsch_channel_compensation() +{: .func4} + * nr_ulsch_compute_llr() +this function creates the "likelyhood ratios" +{: .func4} +* nr_ulsch_procedures() +{: .func4} + * actual ULsch decoding +{: .func4} + * nr_ulsch_unscrambling() + {: .func4} + * nr_ulsch_decoding() + {: .func4} + * nr_fill_indication() +populate the data for the next call to "NR_UL_indication()" +it would be better to call **NR_UL_indication()** now instead of before (on previous slot) +{: .func4} + +### phy_procedures_gNB_TX() +* nr_common_signal_procedures() +generate common signals +{: .func4} +* nr_generate_dci_top() +generate DCI: the scheduling informtion for each UE in both DL and UL +{: .func4} +* nr_generate_pdsch() +generate DL shared channel (user data) +{: .func4} + +### nr_feptx_prec() +tx precoding +{: .func3} +### nr_feptx0 +do the inverse DFT +{: .func3} +### tx_rf() +send radio signal samples to the RF board +the samples numbers are the future time for these samples emission on-air +{: .func3} + +# Scheduler + +The main scheduler function is called by the chain: nr_ul_indication()=>gNB_dlsch_ulsch_scheduler() +It calls sub functions to process each physical channel (rach, ...) +The scheduler uses and internal map of used RB: vrb_map and vrb_map_UL, so each specific channel scheduler can see the already filled RB in each subframe (the function gNB_dlsch_ulsch_scheduler() clears these two arrays when it starts) + +The scheduler also calls "run_pdcp()", as this is not a autonomous thread, it needs to be called here to update traffic requests (DL) and to propagate waiting UL to upper layers +After calling run_pdcp, it updates "rlc" time data but it doesn't actually process rlc +it sends a iiti message to activate the thread for RRC, the answer will be asynchronous in ???? + +Calls schedule_nr_mib() that calls mac_rrc_nr_data_req() to fill MIB, + +Calls schedule_nr_prach() which schedules the (fixed) PRACH region one frame in +advance. + +Calls nr_csi_meas_reporting() to check when to schedule CSI in PUCCH. + +Calls nr_schedule_RA(): checks RA process 0's state. Schedules Msg.2 via +nr_generate_Msg2() if an RA process is ongoing, and pre-allocates the Msg. 3 +for PUSCH as well. + +Calls nr_schedule_ulsch(): It is divided into the "preprocessor" and the +"postprocessor": the first makes the scheduling decisions, the second fills +nFAPI structures to indicate to the PHY what it is supposed to do. To signal +which users have how many resources, the preprocessor populates the +NR_sched_pusch_t (for values changing every TTI, e.g., frequency domain +allocation) and NR_sched_pusch_save_t (for values changing less frequently, at +least in FR1 [to my understanding], e.g., DMRS fields when the time domain +allocation stays between TTIs) structures. Furthermore, the preprocessor is an +exchangeable module that might schedule differently, e.g., one user for +phytest, multiple users in FR1, or maybe FR2: phytest is in +nr_ul_preprocessor_phytest(), for FR1 is nr_simple_ulsch_preprocessor() [under +development], for FR2 does not exist yet. +* calls preprocessor via pre_processor_ul(): the preprocessor is responsible + for allocating CCEs (using allocate_nr_CCEs()). Note that we do not yet have + scheduling requests or buffer status reports, and only one UE. E.g., + nr_simple_ulsch_preprocessor(): + 1) check whether the current frame/slot plus K2 is an UL slot, and return if + not. + 2) Find first free start RB in vrb_map_UL, and as many free consecutive RBs + as possible. + 3) allocate a CCE for the UE (and return if it is not possible) + 4) Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS. + 5) Mark used resources in vrb_map_UL. +* loop through all users: get a free HARQ PID and + update statistics. Fill nFAPI structures directly for PUSCH, and call + config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages. + +Calls nr_schedule_ue_spec(). It is divided into the "preprocessor" and the +"postprocessor": the first makes the scheduling decisions, the second fills +nFAPI structures to indicate to the PHY what it is supposed to do. To signal +which users have how many resources, the preprocessor populates the +NR_UE_sched_ctrl_t structure of affected users. In particular, the field rbSize +decides whether a user is to be allocated. Furthermore, the preprocessor is an +exchangeable module that might schedule differently, e.g., one user for +phytest, multiple users in FR1, or maybe FR2: phytest is in +nr_preprocessor_phytest(), for FR1 is nr_simple_dlsch_preprocessor() [under +development], for FR2 does not exist yet. +* calls preprocessor via pre_processor_dl(): the preprocessor is responsible + for allocating CCEs and PUCCH (using allocate_nr_CCEs() and + nr_acknack_scheduling()) and deciding on the frequency/time domain + allocation. E.g., nr_simple_dlsch_preprocessor(): + 1) mac_rlc_status_ind() locks and checks directly inside rlc data the + quantity of waiting data. + 2) return from the preprocessor if there is no data and no timing advance to + send, + 3) otherwise, allocate a CCE for the UE (and return if it is not possible) + 4) find a PUCCH occasion for HARQ + 5a) check if there is a retransmission: if yes, find free resources to + transmit using the same resources, else + 5b) calculate the necessary RBs needed to get a TBS large enough to hold all + data, or until no more resources are available + 6) Mark taken resources in the vrb_map +* loop through all users: check if a new TA is necessary. Then, if a user has + allocated resources, compute its TBS, and fill nFAPI structures + (nr_fill_nfapi_dl_pdu() to populate what should be done by the lower layers + to make the Tx subframe). Update statistics (round, sent bytes). + +# RRC +RRC is a regular thread with itti loop on queue: TASK_RRC_GNB +it receives it's configuration in message NRRRC_CONFIGURATION_REQ, then real time mesages for all events: S1/NGAP events, X2AP messages and RRC_SUBFRAME_PROCESS + +RRC_SUBFRAME_PROCESS message is send each subframe + +how does it communicate to scheduler ? + + +# RLC +RLC code is new implementation, not using OAI mechanisms: it is implemented directly on pthreads, ignoring OAI common functions. +It is a library, running in thread RRC but also in PHY layer threads and some bits in pdcp running thread or F1 interface threads. + +RLC data is isolated and encapsulated. +It is stored under a global var: nr_rlc_ue_manager +The init function rlc_module_init() populates this global variable. +A small effort could lead us to return the pointer to the caller of rlc_module_init() (internal type: nr_rlc_ue_manager_internal_t) +but it returns void. +It could return the initialized pointer (as FILE* fopen() for example), then the RLC layer could have multiple instances in one process. +Even, a future evolution could remove this global rlc layer: rlc can be only a library that we create a instance for each UE because it doesn't shareany data between UEs. + +For DL (respectively from UL in UE), the scheduler need to know the quantity of data waitin to be sent: it calls mac_rlc_status_ind() +That "peek" the size of the waiting data for a UE. +The scheduler then push orders to lower layers. The transport layer will actually pull data from RLC with: mac_rlc_data_req() +the low layer push data into rlc by: mac_rlc_data_ind() +Still on DL (gNB side), PDCP push incoming data into RLC by calling: rlc_data_req() + +For UL, the low layer push data into rlc by: mac_rlc_data_ind() +Then, rlc push it to pdcp by calling pdcp_data_ind() from a complex rlc internal call back (deliver_sdu()) + +When adding a UE, external code have to call nr_rrc_rlc_config_asn1_req(), to remove it: rrc_rlc_remove_ue() +Inside UE, channels called drd or srb can be created: ??? and deleted: rrc_rlc_config_req() + +nr_rlc_tick() must be called periodically to manage the internal timers + +successful_delivery() and max_retx_reached(): in ??? trigger, the RLC sends a itti message to RRC: RLC_SDU_INDICATION (neutralized by #if 0 right now) + +#PDCP + +The PDCP implementation is also protected through a general mutex. +The design is very similar to rlc layer. The pdcp data is isolated and encapsulated. + +pdcp_layer_init(): same as rlc init +we have to call a second init function: pdcp_module_init() + +At Tx side (DL in gNB), pdcp_data_req() is the entry function that the upper layer calls. +The upper layer can be GTP or a PDCP internal thread enb_tun_read_thread() that read directly from Linux socket in case we skip 3GPP core implementation. +PDCP internals for pdcp_data_req() is thread safe: inside pdcp_data_req_drb(), the pdcp manager protects with the mutex the access to the SDU receiving function of PDCP (recv_sdu() callback, corresponding to nr_pdcp_entity_drb_am_recv_sdu() for DRBs). When it needs, the pdcp layer push this data to rlc by calling : rlc_data_req() + +Also, incoming downlink sdu can comme from internal RRC: in this case, pdcp_run() reads a itti queue, for message RRC_DCCH_DATA_REQ, to0 only call 'pdcp_data_req()' + +At Rx side, pdcp_data_ind() is the entry point that receives the data from RLC. +- Inside pdcp_data_ind(), the pdcp manager mutex protects the access to the PDU receiving function of PDCP (recv_pdu() callback corresponding to nr_pdcp_entity_drb_am_recv_pdu() for DRBs) +- Then deliver_sdu_drb() function sends the received data to GTP thread through an ITTI message (GTPV1U_ENB_TUNNEL_DATA_REQ). + +pdcp_config_set_security(): not yet developped + +nr_DRB_preconfiguration(): the mac layer calls this for ??? + +nr_rrc_pdcp_config_asn1_req() adds a UE in pdcp, pdcp_remove_UE() removes it + +# GTP +Gtp + UDP are two twin threads performing the data plane interface to the core network +The design is hybrid: thread and inside other threads calls. It should at least be protected by a mutex. +## GTP thread +Gtp thread has a itti interface: queue TASK_GTPV1_U +The interface is about full definition: control messages (create/delet GTP tunnels) and data messages (user plane UL and DL). +PDCP layer push to the GTP queue (outside UDP thread that do almost nothing and work only with GTP thread) is to push a UL packet. + + +## GTP thread running code from other layers +gtp thread calls directly pdcp_data_req(), so it runs inside it's context internal pdcp structures updates + +## inside other threads +gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex. + +# NGAP +NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)? +About all messages are exchanged with RRC thread + + +
+**Note** +{: .panel-heading} +
+ + +
+
+ diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 17f37ad2d7..610cc5bdd4 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -1,18 +1,31 @@ -STATUS 2020/09/10 : updated the status of interop (end to end UL/DL traffic) +STATUS 2020/10/15 : added External Resources section and links ## Table of Contents ## -1. [Configuration Overview](#configuration-overview) -2. [SW Repository / Branch](#repository) -3. [Architecture Setup](#architecture-setup) -4. [Build / Install](#build-and-install) -5. [Run / Test](#run-and-test) -6. [Test case](#test-case) -7. [Log file monitoring](#log-file-monitoring) -6. [Required tools for debug](#required-tools-for-debug) -7. [Status of interoperability](#status-of-interoperability) -8. [CI integration](#ci-integration) +1. [External Resources](#external-resources) +2. [Configuration Overview](#configuration-overview) +3. [SW Repository / Branch](#repository) +4. [Architecture Setup](#architecture-setup) +5. [Build / Install](#build-and-install) +6. [Run / Test](#run-and-test) +7. [Test case](#test-case) +8. [Log file monitoring](#log-file-monitoring) +9. [Required tools for debug](#required-tools-for-debug) +10. [Status of interoperability](#status-of-interoperability) +11. [CI integration](#ci-integration) + + +## External Resources + +Additional Resources to this page can be found here (special mention to Walter Maguire ) : +https://docs.google.com/document/d/1pL8Szm0ocGxdl5ESVp12Ff71a4PbhCb9SpvbLZzwYbo/edit?usp=sharing +At time of writing, the openairinterface5G Commit Tag is 2020.w39 + + +Faraday Cages can be found here : +http://www.saelig.com/MFR00066/ste2300.htm + ## Configuration Overview diff --git a/docker/Dockerfile.eNB.rhel7.oc4-4 b/docker/Dockerfile.eNB.rhel7.oc4-4 new file mode 100644 index 0000000000..85c2a17ead --- /dev/null +++ b/docker/Dockerfile.eNB.rhel7.oc4-4 @@ -0,0 +1,83 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL7 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + +FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:latest AS enb-build + + +WORKDIR /oai-enb +COPY . . + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai --eNB + + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi7/ubi:latest as oai-enb + +# Entitlements and RHSM configurations are Open-Shift Secret and ConfigMaps +# It is pre-requisite +RUN rm -Rf /etc/rhsm/ca /etc/pki/entitlement +# Copy the entitlements +COPY ./etc-pki-entitlement /etc/pki/entitlement +# Copy the subscription manager configurations +COPY ./rhsm-conf /etc/rhsm +COPY ./rhsm-ca /etc/rhsm/ca + + +#install developers pkg/repo +RUN rm /etc/rhsm-host && \ + # Initialize /etc/yum.repos.d/redhat.repo + # See https://access.redhat.com/solutions/1443553 + yum repolist --disablerepo=* && \ + yum-config-manager --enable rhel-7-server-optional-rpms rhel-server-rhscl-7-rpms && \ + yum update -y && \ + yum install -y \ + lksctp-tools \ + protobuf-c \ + nettle \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf + + +WORKDIR /opt/oai-enb/bin +COPY --from=enb-build /oai-enb/targets/bin/lte-softmodem.Rel15 . + +RUN ldd lte-softmodem.Rel15 + +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] + diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 new file mode 100644 index 0000000000..5fcd5a7b9f --- /dev/null +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -0,0 +1,125 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 +# +#--------------------------------------------------------------------- + +FROM localhost/ran-build:latest AS enb-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --eNB --ninja -w USRP + +# debug +#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15 +#RUN ls -ls /oai-ran/targets/bin +#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-enb + +RUN yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + lksctp-tools \ + nettle \ + atlas \ + net-tools \ + iputils \ + iproute \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-enb/bin +COPY --from=enb-build /oai-ran/targets/bin/lte-softmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=enb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/libcoding.so . +COPY --from=enb-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=enb-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=enb-build /oai-ran/cmake_targets/ran_build/build/liboai_iqplayer.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=enb-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=enb-build /lib64/libconfig.so.9 /lib64 +COPY --from=enb-build /lib64/libblas.so.3 /lib64 +COPY --from=enb-build /lib64/liblapack.so.3 /lib64 +COPY --from=enb-build /lib64/liblapacke.so.3 /lib64 +COPY --from=enb-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=enb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig + +#debug +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libdfts.so +#RUN ldd /usr/local/lib/liboai_iqplayer.so +#RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15 + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-enb/etc +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/enb.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rcc.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/cu.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/du.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rru.* . + +WORKDIR /opt/oai-enb + +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.eNB.rhel8.2.oc4-4 b/docker/Dockerfile.eNB.rhel8.2.oc4-4 new file mode 100644 index 0000000000..5b784c08a2 --- /dev/null +++ b/docker/Dockerfile.eNB.rhel8.2.oc4-4 @@ -0,0 +1,126 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + +FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:rhel8-latest AS enb-build + + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --eNB --ninja -w USRP + +# debug +#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15 +#RUN ls -ls /oai-ran/targets/bin +#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-enb + +RUN yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + lksctp-tools \ + nettle \ + atlas \ + net-tools \ + iproute \ + iputils \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-enb/bin +COPY --from=enb-build /oai-ran/targets/bin/lte-softmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=enb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/libcoding.so . +COPY --from=enb-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=enb-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=enb-build /oai-ran/cmake_targets/ran_build/build/liboai_iqplayer.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=enb-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=enb-build /lib64/libconfig.so.9 /lib64 +COPY --from=enb-build /lib64/libblas.so.3 /lib64 +COPY --from=enb-build /lib64/liblapack.so.3 /lib64 +COPY --from=enb-build /lib64/liblapacke.so.3 /lib64 +COPY --from=enb-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=enb-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=enb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig + +#debug +RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +RUN ldd /usr/local/lib/libcoding.so +RUN ldd /usr/local/lib/libparams_libconfig.so +RUN ldd /usr/local/lib/libdfts.so +RUN ldd /usr/local/lib/liboai_iqplayer.so +RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15 + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-enb/etc +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/enb.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rcc.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/cu.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/du.* . +COPY --from=enb-build /oai-ran/ci-scripts/conf_files/rru.* . + +WORKDIR /opt/oai-enb + +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 new file mode 100644 index 0000000000..cdfb37ebfc --- /dev/null +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -0,0 +1,126 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu 18.04 +# +#--------------------------------------------------------------------- + +FROM ran-build:latest AS enb-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --eNB --ninja -w USRP + +RUN apt-get install -y python3-pip && \ + pip3 install --ignore-installed pyyaml && \ + python3 ./docker/scripts/generateTemplate.py ./docker/scripts/enb_parameters.yaml + +# debug +#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-softmodem.Rel15 +#RUN ls -ls /oai-ran/targets/bin +#RUN ls -ls /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM ubuntu:bionic as oai-enb +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + software-properties-common \ + libsctp1 \ + libnettle6 \ + libblas3 \ + libatlas3-base \ + libconfig9 \ + openssl \ + net-tools \ + iputils-ping \ + iproute2 \ + libyaml-0-2 && \ + # Install UHD driver from ettus ppa + # At time of writing, it is 3.14 + add-apt-repository ppa:ettusresearch/uhd --yes && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + python \ + libusb-1.0-0 \ + libuhd003 \ + uhd-host && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-enb/bin +COPY --from=enb-build /oai-ran/targets/bin/lte-softmodem.Rel15 . +COPY --from=enb-build /oai-ran/docker/scripts/enb_entrypoint.sh entrypoint.sh + +WORKDIR /usr/local/lib/ +COPY --from=enb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=enb-build /oai-ran/targets/bin/libcoding.so . +COPY --from=enb-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=enb-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=enb-build /oai-ran/cmake_targets/ran_build/build/liboai_iqplayer.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=enb-build /usr/local/lib/libprotobuf-c.so.1 . + +RUN ldconfig + +#debug +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libdfts.so +#RUN ldd /usr/local/lib/liboai_iqplayer.so +#RUN ldd /opt/oai-enb/bin/lte-softmodem.Rel15 + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-enb/etc +COPY --from=enb-build /oai-ran/docker/etc . + +WORKDIR /opt/oai-enb + +# 2152 --> S1U, GTP/UDP +# 36412 --> S1C, SCTP/UDP +# 36422 --> X2C, SCTP/UDP +EXPOSE 2152/udp 36412/udp 36422/udp +#EXPOSE 22100/tcp # ? +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] +CMD ["/opt/oai-enb/bin/lte-softmodem.Rel15", "-O", "/opt/oai-enb/etc/enb.conf"] diff --git a/docker/Dockerfile.enb.rhel7.oc4-4 b/docker/Dockerfile.enb.rhel7.oc4-4 deleted file mode 100644 index 12d9a19640..0000000000 --- a/docker/Dockerfile.enb.rhel7.oc4-4 +++ /dev/null @@ -1,92 +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 -# */ -#--------------------------------------------------------------------- -# -# Dockerfile for the Open-Air-Interface eNB service -# Valid for RHEL7 in the OpenShift context (v4.4) -# -#--------------------------------------------------------------------- - - -ARG REGISTRY=localhost -FROM $REGISTRY/oai-build-base:latest.el7 AS builder - -ARG GIT_TAG=v1.1.1 - -WORKDIR /root - -RUN if [ "$EURECOM_PROXY" == true ]; then git config --global http.proxy http://:@proxy.eurecom.fr:8080; fi - -RUN git clone --depth=1 --branch=$GIT_TAG https://gitlab.eurecom.fr/oai/openairinterface5g.git -COPY patches patches/ -RUN patch -p1 -d openairinterface5g < patches/disable_building_nasmesh_and_rbtool.patch \ - && patch -p1 -d openairinterface5g < patches/disable_sched_fifo_fail_exits.patch -RUN cd openairinterface5g/cmake_targets \ - && ln -sf /usr/local/bin/asn1c_oai /usr/local/bin/asn1c \ - && ln -sf /usr/local/share/asn1c_oai /usr/local/share/asn1c \ - && ./build_oai -c --eNB -w USRP --verbose-compile - - -FROM registry.redhat.io/ubi7/ubi -LABEL name="oai-enb" \ - version="$GIT_TAG" \ - maintainer="Frank A. Zdarsky " \ - io.k8s.description="openairinterface5g eNB $GIT_TAG." \ - io.openshift.tags="oai,enb" \ - io.openshift.non-scalable="true" - -RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \ - && REPOLIST="rhel-7-server-optional-rpms" \ - && PKGLIST="boost libconfig lksctp-tools protobuf-c iproute iputils procps-ng bind-utils xforms nettle libyaml libusb" \ - # && yum -y upgrade-minimal --setopt=tsflags=nodocs --security --sec-severity=Critical --sec-severity=Important && \ - && yum -y install --enablerepo ${REPOLIST} --setopt=tsflag=nodocs ${PKGLIST} \ - && yum -y clean all \ - && rm -rf /var/cache/yum - -ENV APP_ROOT=/opt/oai-enb -ENV PATH=${APP_ROOT}:${PATH} HOME=${APP_ROOT} -COPY --from=builder /root/openairinterface5g/cmake_targets/lte_build_oai/build/lte-softmodem ${APP_ROOT}/bin/ -COPY --from=builder /root/openairinterface5g/cmake_targets/lte_build_oai/build/*.so* /lib64 -COPY --from=builder /usr/local/lib64 /lib64 -COPY --from=builder /usr/local/bin/uhd_* /usr/local/bin -COPY --from=builder /usr/local/share/uhd /usr/local/share/uhd -RUN cd /lib64 \ - && ln -sf liboai_eth_transpro.so liboai_transpro.so \ - && ln -sf liboai_usrpdevif.so liboai_device.so \ - && ln -sf libuhd.so.3.13 libuhd.so.3 \ - && ln -sf libuhd.so.3 libuhd.so -COPY scripts ${APP_ROOT}/bin/ -COPY configs ${APP_ROOT}/etc/ -RUN chmod -R u+x ${APP_ROOT} && \ - chgrp -R 0 ${APP_ROOT} && \ - chmod -R g=u ${APP_ROOT} /etc/passwd -USER 10001 -WORKDIR ${APP_ROOT} - -EXPOSE 2152/udp # S1U, GTP/UDP -EXPOSE 22100/tcp # ? -EXPOSE 36412/udp # S1C, SCTP/UDP -EXPOSE 36422/udp # X2C, SCTP/UDP -EXPOSE 50000/udp # IF5 / ORI (control) -EXPOSE 50001/udp # IF5 / ECPRI (data) - -CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"] -ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"] diff --git a/docker/Dockerfile.gNB.rhel7.oc4-4 b/docker/Dockerfile.gNB.rhel7.oc4-4 new file mode 100644 index 0000000000..5165dd9715 --- /dev/null +++ b/docker/Dockerfile.gNB.rhel7.oc4-4 @@ -0,0 +1,89 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL7 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + +FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:latest AS gnb-build + + +WORKDIR /oai-gnb +COPY . . + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai --gNB + + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi7/ubi:latest as oai-gnb + +# Entitlements and RHSM configurations are Open-Shift Secret and ConfigMaps +# It is pre-requisite +RUN rm -Rf /etc/rhsm/ca /etc/pki/entitlement +# Copy the entitlements +COPY ./etc-pki-entitlement /etc/pki/entitlement +# Copy the subscription manager configurations +COPY ./rhsm-conf /etc/rhsm +COPY ./rhsm-ca /etc/rhsm/ca + + +#install developers pkg/repo +RUN rm /etc/rhsm-host && \ + # Initialize /etc/yum.repos.d/redhat.repo + # See https://access.redhat.com/solutions/1443553 + yum repolist --disablerepo=* && \ + yum-config-manager --enable rhel-7-server-optional-rpms rhel-server-rhscl-7-rpms && \ + yum update -y && \ + yum install -y \ + libXpm \ + libX11 \ + atlas \ + blas \ + lapack \ + lksctp-tools \ + protobuf-c \ + nettle \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build /oai-gnb/targets/bin/nr-softmodem.Rel15 . +WORKDIR /lib64 +COPY --from=gnb-build /lib64/libforms.so.2 . + +RUN ldd /opt/oai-gnb/bin/nr-softmodem.Rel15 + +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +#ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] + diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 new file mode 100644 index 0000000000..fb9ade927f --- /dev/null +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 +# +#--------------------------------------------------------------------- + +FROM localhost/ran-build:latest AS gnb-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --gNB --ninja -w USRP + +#debug +#RUN ldconfig -v +#RUN ldd /oai-ran/targets/bin/nr-softmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-gnb + +RUN yum repolist --disablerepo=* && \ + yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + libXpm \ + libX11 \ + atlas \ + lksctp-tools \ + nettle \ + net-tools \ + iputils \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build /oai-ran/targets/bin/nr-softmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=gnb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/libcoding.so . +COPY --from=gnb-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so . + +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" +COPY --from=gnb-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=gnb-build /lib64/libconfig.so.9 /lib64 +COPY --from=gnb-build /lib64/libforms.so.2 /lib64 +COPY --from=gnb-build /lib64/libblas.so.3 /lib64 +COPY --from=gnb-build /lib64/liblapack.so.3 /lib64 +COPY --from=gnb-build /lib64/liblapacke.so.3 /lib64 +COPY --from=gnb-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=gnb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig +#debug +#RUN ldd /opt/oai-gnb/bin/nr-softmodem.Rel15 +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libdfts.so +#RUN ldd /usr/local/lib/libldpc.so +#RUN ldd /usr/local/lib/libldpc_optim.so +#RUN ldd /usr/local/lib/libldpc_optim8seg.so +#RUN ldd /usr/local/lib/libldpc_orig.so + +# Copy the relevant configuration files for gNB +WORKDIR /opt/oai-gnb/etc +COPY --from=gnb-build /oai-ran/ci-scripts/conf_files/gnb.* . + +WORKDIR /opt/oai-gnb +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +#ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.gNB.rhel8.2.oc4-4 b/docker/Dockerfile.gNB.rhel8.2.oc4-4 new file mode 100644 index 0000000000..1e1eba016e --- /dev/null +++ b/docker/Dockerfile.gNB.rhel8.2.oc4-4 @@ -0,0 +1,130 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + +FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:rhel8-latest AS gnb-build + + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --gNB --ninja -w USRP + +#debug +#RUN ldconfig -v +#RUN ldd /oai-ran/targets/bin/nr-softmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-gnb + +RUN yum repolist --disablerepo=* && \ + yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + libXpm \ + libX11 \ + atlas \ + lksctp-tools \ + nettle \ + net-tools \ + iputils \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build /oai-ran/targets/bin/nr-softmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=gnb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/libcoding.so . +COPY --from=gnb-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so . + +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" +COPY --from=gnb-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=gnb-build /lib64/libconfig.so.9 /lib64 +COPY --from=gnb-build /lib64/libforms.so.2 /lib64 +COPY --from=gnb-build /lib64/libblas.so.3 /lib64 +COPY --from=gnb-build /lib64/liblapack.so.3 /lib64 +COPY --from=gnb-build /lib64/liblapacke.so.3 /lib64 +COPY --from=gnb-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=gnb-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=gnb-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig +#debug +RUN ldd /opt/oai-gnb/bin/nr-softmodem.Rel15 +RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +RUN ldd /usr/local/lib/libcoding.so +RUN ldd /usr/local/lib/libparams_libconfig.so +RUN ldd /usr/local/lib/libdfts.so +RUN ldd /usr/local/lib/libldpc.so +RUN ldd /usr/local/lib/libldpc_optim.so +RUN ldd /usr/local/lib/libldpc_optim8seg.so +RUN ldd /usr/local/lib/libldpc_orig.so + +# Copy the relevant configuration files for gNB +WORKDIR /opt/oai-gnb/etc +COPY --from=gnb-build /oai-ran/ci-scripts/conf_files/gnb.* . + +WORKDIR /opt/oai-gnb +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +#ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 new file mode 100644 index 0000000000..d43ad4709d --- /dev/null +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -0,0 +1,126 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu18.04 +# +#--------------------------------------------------------------------- + +FROM ran-build:latest AS gnb-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --gNB --ninja -w USRP + +#debug +RUN ldconfig -v +RUN ldd /oai-ran/targets/bin/nr-softmodem.Rel15 +RUN ls -lst /oai-ran/targets/bin +RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM ubuntu:bionic as oai-gnb +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + software-properties-common \ + libsctp1 \ + libnettle6 \ + libblas3 \ + libatlas3-base \ + libconfig9 \ + openssl \ + net-tools \ + iproute2 \ + iputils-ping \ + libyaml-0-2 && \ + # Install UHD driver from ettus ppa + # At time of writing, it is 3.14 + add-apt-repository ppa:ettusresearch/uhd --yes && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + python \ + libusb-1.0-0 \ + libuhd003 \ + uhd-host && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-gnb/bin +COPY --from=gnb-build /oai-ran/targets/bin/nr-softmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=gnb-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=gnb-build /oai-ran/targets/bin/libcoding.so . +COPY --from=gnb-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so . +COPY --from=gnb-build /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so . + +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" +COPY --from=gnb-build /usr/local/lib/libprotobuf-c.so.1 . + +RUN ldconfig +#debug +#RUN ldd /opt/oai-gnb/bin/nr-softmodem.Rel15 +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libdfts.so +#RUN ldd /usr/local/lib/libldpc.so +#RUN ldd /usr/local/lib/libldpc_optim.so +#RUN ldd /usr/local/lib/libldpc_optim8seg.so +#RUN ldd /usr/local/lib/libldpc_orig.so + +# Copy the relevant configuration files for gNB +WORKDIR /opt/oai-gnb/etc +COPY --from=gnb-build /oai-ran/ci-scripts/conf_files/gnb.* ./ + +WORKDIR /opt/oai-gnb +#EXPOSE 2152/udp # S1U, GTP/UDP +#EXPOSE 22100/tcp # ? +#EXPOSE 36412/udp # S1C, SCTP/UDP +#EXPOSE 36422/udp # X2C, SCTP/UDP +#EXPOSE 50000/udp # IF5 / ORI (control) +#EXPOSE 50001/udp # IF5 / ECPRI (data) + +#CMD ["/opt/oai-gnb/bin/nr-softmodem", "-O", "/opt/oai-gnb/etc/gnb.conf"] +#ENTRYPOINT ["/opt/oai-gnb/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 new file mode 100644 index 0000000000..0a853dcd6b --- /dev/null +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -0,0 +1,124 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 +# +#--------------------------------------------------------------------- + +FROM localhost/ran-build:latest AS lte-ue-build + + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --UE --ninja -w USRP + +# debug +#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ue + +RUN yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + lksctp-tools \ + nettle \ + atlas \ + iproute \ + net-tools \ + iputils \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-lte-ue/bin +COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata . +COPY --from=lte-ue-build /oai-ran/targets/bin/nvram . +COPY --from=lte-ue-build /oai-ran/targets/bin/usim . +COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 . +COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 . +COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 . + +WORKDIR /usr/local/lib/ +COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/libcoding.so . +COPY --from=lte-ue-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=lte-ue-build /oai-ran/cmake_targets/ran_build/build/libSIMU.so . +COPY --from=lte-ue-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=lte-ue-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=lte-ue-build /lib64/libconfig.so.9 /lib64 +COPY --from=lte-ue-build /lib64/libblas.so.3 /lib64 +COPY --from=lte-ue-build /lib64/liblapack.so.3 /lib64 +COPY --from=lte-ue-build /lib64/liblapacke.so.3 /lib64 +COPY --from=lte-ue-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=lte-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig + +#debug +#RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15 +#RUN ldd /opt/oai-lte-ue/bin/conf2uedata +#RUN ldd /opt/oai-lte-ue/bin/nvram +#RUN ldd /opt/oai-lte-ue/bin/usim +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libSIMU.so +#RUN ldd /usr/local/lib/libdfts.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-lte-ue/etc +COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* . +COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf + +WORKDIR /opt/oai-lte-ue +#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.lteUE.rhel8.2.oc4-4 b/docker/Dockerfile.lteUE.rhel8.2.oc4-4 new file mode 100644 index 0000000000..1339d18de6 --- /dev/null +++ b/docker/Dockerfile.lteUE.rhel8.2.oc4-4 @@ -0,0 +1,124 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + +FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:rhel8-latest AS lte-ue-build + + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --UE --ninja -w USRP + +# debug +#RUN ldconfig -v && ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-lte-ue + +RUN yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + lksctp-tools \ + nettle \ + atlas \ + iproute \ + net-tools \ + iputils \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-lte-ue/bin +COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata . +COPY --from=lte-ue-build /oai-ran/targets/bin/nvram . +COPY --from=lte-ue-build /oai-ran/targets/bin/usim . +COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 . +COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 . +COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 . + +WORKDIR /usr/local/lib/ +COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/libcoding.so . +COPY --from=lte-ue-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=lte-ue-build /oai-ran/cmake_targets/ran_build/build/libSIMU.so . +COPY --from=lte-ue-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=lte-ue-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=lte-ue-build /lib64/libconfig.so.9 /lib64 +COPY --from=lte-ue-build /lib64/libblas.so.3 /lib64 +COPY --from=lte-ue-build /lib64/liblapack.so.3 /lib64 +COPY --from=lte-ue-build /lib64/liblapacke.so.3 /lib64 +COPY --from=lte-ue-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=lte-ue-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=lte-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig + +#debug +RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15 +RUN ldd /opt/oai-lte-ue/bin/conf2uedata +RUN ldd /opt/oai-lte-ue/bin/nvram +RUN ldd /opt/oai-lte-ue/bin/usim +RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +RUN ldd /usr/local/lib/libcoding.so +RUN ldd /usr/local/lib/libparams_libconfig.so +RUN ldd /usr/local/lib/libSIMU.so +RUN ldd /usr/local/lib/libdfts.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-lte-ue/etc +COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* . +COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf + +WORKDIR /opt/oai-lte-ue +#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 new file mode 100644 index 0000000000..8793cc54f7 --- /dev/null +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -0,0 +1,124 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu18.04 +# +#--------------------------------------------------------------------- + +FROM ran-build:latest AS lte-ue-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --UE --ninja -w USRP + +# debug +#RUN ldconfig -v +#RUN ldd /oai-ran/targets/bin/lte-uesoftmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM ubuntu:bionic as oai-lte-ue +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + software-properties-common \ + libsctp1 \ + libnettle6 \ + liblapacke \ + libatlas3-base \ + libconfig9 \ + openssl \ + net-tools \ + iputils-ping \ + iproute2 \ + libyaml-0-2 && \ + # Install UHD driver from ettus ppa + # At time of writing, it is 3.14 + add-apt-repository ppa:ettusresearch/uhd --yes && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + python \ + libusb-1.0-0 \ + libuhd003 \ + uhd-host && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-lte-ue/bin +COPY --from=lte-ue-build /oai-ran/targets/bin/lte-uesoftmodem.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/conf2uedata . +COPY --from=lte-ue-build /oai-ran/targets/bin/nvram . +COPY --from=lte-ue-build /oai-ran/targets/bin/usim . +COPY --from=lte-ue-build /oai-ran/targets/bin/.ue_emm.nvram0 . +COPY --from=lte-ue-build /oai-ran/targets/bin/.ue.nvram0 . +COPY --from=lte-ue-build /oai-ran/targets/bin/.usim.nvram0 . + +WORKDIR /usr/local/lib/ +COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=lte-ue-build /oai-ran/targets/bin/libcoding.so . +COPY --from=lte-ue-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=lte-ue-build /oai-ran/cmake_targets/ran_build/build/libSIMU.so . +COPY --from=lte-ue-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=lte-ue-build /usr/local/lib/libprotobuf-c.so.1 . + +RUN ldconfig + +#debug +#RUN ldd /opt/oai-lte-ue/bin/lte-uesoftmodem.Rel15 +#RUN ldd /opt/oai-lte-ue/bin/conf2uedata +#RUN ldd /opt/oai-lte-ue/bin/nvram +#RUN ldd /opt/oai-lte-ue/bin/usim +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libSIMU.so +#RUN ldd /usr/local/lib/libdfts.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-lte-ue/etc +COPY --from=lte-ue-build /oai-ran/ci-scripts/conf_files/ue.* ./ +COPY --from=lte-ue-build /oai-ran/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf ./ue_usim.conf + +WORKDIR /opt/oai-lte-ue +#CMD ["/opt/oai-lte-ue/bin/lte-uesoftmodem", "-O", "/opt/oai-lte-ue/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-lte-ue/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 new file mode 100644 index 0000000000..f9f3f8e4bf --- /dev/null +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -0,0 +1,120 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 +# +#--------------------------------------------------------------------- + +FROM localhost/ran-build:latest AS nr-ue-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --nrUE --ninja -w USRP + +# debug +#RUN ldconfig -v +#RUN ldd /oai-ran/targets/bin/nr-uesoftmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-nr-ue + +RUN yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + lksctp-tools \ + nettle \ + net-tools \ + iputils \ + atlas \ + libXpm \ + libX11 \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-nr-ue/bin +COPY --from=nr-ue-build /oai-ran/targets/bin/nr-uesoftmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/libcoding.so . +COPY --from=nr-ue-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=nr-ue-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=nr-ue-build /lib64/libconfig.so.9 /lib64 +COPY --from=nr-ue-build /lib64/libblas.so.3 /lib64 +COPY --from=nr-ue-build /lib64/liblapack.so.3 /lib64 +COPY --from=nr-ue-build /lib64/liblapacke.so.3 /lib64 +COPY --from=nr-ue-build /lib64/libforms.so.2 /lib64 +COPY --from=nr-ue-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=nr-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig +#RUN ldd /opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15 +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libdfts.so +#RUN ldd /usr/local/lib/libldpc.so +#RUN ldd /usr/local/lib/libldpc_optim.so +#RUN ldd /usr/local/lib/libldpc_optim8seg.so +#RUN ldd /usr/local/lib/libldpc_orig.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-nr-ue/etc +COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . + +WORKDIR /opt/oai-nr-ue +#CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.nrUE.rhel8.2.oc4-4 b/docker/Dockerfile.nrUE.rhel8.2.oc4-4 new file mode 100644 index 0000000000..d900fff998 --- /dev/null +++ b/docker/Dockerfile.nrUE.rhel8.2.oc4-4 @@ -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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + +FROM image-registry.openshift-image-registry.svc:5000/oai/oai-ran:rhel8-latest AS nr-ue-build + + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --nrUE --ninja -w USRP + +# debug +#RUN ldconfig -v +#RUN ldd /oai-ran/targets/bin/nr-uesoftmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM registry.access.redhat.com/ubi8/ubi:latest as oai-nr-ue + +RUN yum update -y && \ + yum install -y --enablerepo="ubi-8-codeready-builder" \ + lksctp-tools \ + nettle \ + net-tools \ + iputils \ + atlas \ + libXpm \ + libX11 \ + libyaml && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +WORKDIR /opt/oai-nr-ue/bin +COPY --from=nr-ue-build /oai-ran/targets/bin/nr-uesoftmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/libcoding.so . +COPY --from=nr-ue-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=nr-ue-build /usr/local/lib/libprotobuf-c.so.1 . + +COPY --from=nr-ue-build /lib64/libconfig.so.9 /lib64 +COPY --from=nr-ue-build /lib64/libblas.so.3 /lib64 +COPY --from=nr-ue-build /lib64/liblapack.so.3 /lib64 +COPY --from=nr-ue-build /lib64/liblapacke.so.3 /lib64 +COPY --from=nr-ue-build /lib64/libforms.so.2 /lib64 +COPY --from=nr-ue-build /lib64/libboost_chrono.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_date_time.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_filesystem.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_program_options.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_serialization.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_thread.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_system.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_unit_test_framework.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_atomic.so.1.66.0 /lib64 +COPY --from=nr-ue-build /lib64/libboost_timer.so.1.66.0 /lib64 +COPY --from=nr-ue-build /usr/local/lib64/libuhd.so.4.0.0 /usr/local/lib64 + +RUN ldconfig +RUN ldd /opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15 +RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +RUN ldd /usr/local/lib/libcoding.so +RUN ldd /usr/local/lib/libparams_libconfig.so +RUN ldd /usr/local/lib/libdfts.so +RUN ldd /usr/local/lib/libldpc.so +RUN ldd /usr/local/lib/libldpc_optim.so +RUN ldd /usr/local/lib/libldpc_optim8seg.so +RUN ldd /usr/local/lib/libldpc_orig.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-nr-ue/etc +COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . + +WORKDIR /opt/oai-nr-ue +#CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 new file mode 100644 index 0000000000..5450194f35 --- /dev/null +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -0,0 +1,119 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu 18.04 +# +#--------------------------------------------------------------------- + +FROM ran-build:latest AS nr-ue-build + +WORKDIR /oai-ran + +#run build_oai to build the target image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + rm -Rf log && \ + mkdir -p log && \ + ./build_oai --nrUE --ninja -w USRP + +# debug +#RUN ldconfig -v +#RUN ldd /oai-ran/targets/bin/nr-uesoftmodem.Rel15 +#RUN ls -lst /oai-ran/targets/bin +#RUN ls -lst /oai-ran/cmake_targets/ran_build/build/*.so + +#start from scratch for target executable +FROM ubuntu:bionic as oai-nr-ue +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + software-properties-common \ + libsctp1 \ + libnettle6 \ + liblapacke \ + libatlas3-base \ + libconfig9 \ + openssl \ + net-tools \ + iputils-ping \ + iproute2 \ + libyaml-0-2 && \ + # Install UHD driver from ettus ppa + # At time of writing, it is 3.14 + add-apt-repository ppa:ettusresearch/uhd --yes && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + python \ + libusb-1.0-0 \ + libuhd003 \ + uhd-host && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/oai-nr-ue/bin +COPY --from=nr-ue-build /oai-ran/targets/bin/nr-uesoftmodem.Rel15 . + +WORKDIR /usr/local/lib/ +COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_eth_transpro.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/libtcp_bridge_oai.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/librfsimulator.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/liboai_usrpdevif.so.Rel15 . +COPY --from=nr-ue-build /oai-ran/targets/bin/libcoding.so . +COPY --from=nr-ue-build /oai-ran/targets/bin/libparams_libconfig.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libdfts.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_optim8seg.so . +COPY --from=nr-ue-build /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so . +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_eth_transpro.so.Rel15 /usr/local/lib/liboai_transpro.so" +RUN /bin/bash -c "ln -s /usr/local/lib/liboai_usrpdevif.so.Rel15 /usr/local/lib/liboai_device.so" +RUN /bin/bash -c "ln -s /usr/local/lib/librfsimulator.so.Rel15 /usr/local/lib/librfsimulator.so" + +COPY --from=nr-ue-build /usr/local/lib/libprotobuf-c.so.1 . + +RUN ldconfig +#debug +#RUN ldd /opt/oai-nr-ue/bin/nr-uesoftmodem.Rel15 +#RUN ldd /usr/local/lib/liboai_eth_transpro.so.Rel15 +#RUN ldd /usr/local/lib/libtcp_bridge_oai.so.Rel15 +#RUN ldd /usr/local/lib/librfsimulator.so.Rel15 +#RUN ldd /usr/local/lib/liboai_usrpdevif.so.Rel15 +#RUN ldd /usr/local/lib/libcoding.so +#RUN ldd /usr/local/lib/libparams_libconfig.so +#RUN ldd /usr/local/lib/libdfts.so +#RUN ldd /usr/local/lib/libldpc.so +#RUN ldd /usr/local/lib/libldpc_optim.so +#RUN ldd /usr/local/lib/libldpc_optim8seg.so +#RUN ldd /usr/local/lib/libldpc_orig.so + +# Copy the relevant configuration files for eNB +WORKDIR /opt/oai-nr-ue/etc +COPY --from=nr-ue-build /oai-ran/ci-scripts/conf_files/ue.* . + +WORKDIR /opt/oai-nr-ue +#CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem", "-O", "/opt/oai-nr-ue/etc/enb.conf"] +#ENTRYPOINT ["/opt/oai-nr-ue/bin/entrypoint.sh"] +CMD ["sleep", "infinity"] diff --git a/docker/Dockerfile.ran.rhel7.oc4-4 b/docker/Dockerfile.ran.rhel7.oc4-4 new file mode 100644 index 0000000000..e32fa9b36d --- /dev/null +++ b/docker/Dockerfile.ran.rhel7.oc4-4 @@ -0,0 +1,74 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL7 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + + +FROM registry.access.redhat.com/ubi7/ubi:latest AS ran-build + +# Entitlements and RHSM configurations are Open-Shift Secret and ConfigMaps +# It is pre-requisite +RUN rm -Rf /etc/rhsm/ca /etc/pki/entitlement +# Copy the entitlements +COPY ./etc-pki-entitlement /etc/pki/entitlement +# Copy the subscription manager configurations +COPY ./rhsm-conf /etc/rhsm +COPY ./rhsm-ca /etc/rhsm/ca + + +#install developers pkg/repo +RUN rm /etc/rhsm-host && \ + # Initialize /etc/yum.repos.d/redhat.repo + # See https://access.redhat.com/solutions/1443553 + yum repolist --disablerepo=* && \ + yum-config-manager --enable rhel-7-server-optional-rpms rhel-server-rhscl-7-rpms && \ + yum update -y && \ + yum install -y \ + #gcc needed for build_oai + gcc gcc-c++ \ + diffutils \ + file \ + psmisc \ + git \ + #unzip is needed for protobuf + unzip && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf + +# In some network environments, GIT proxy is required +RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" + +#create the WORKDIR +WORKDIR /oai-ran +COPY . . + +#run build_oai -I to get the builder image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -I + +#as the image is public, we need to remove the subscription manager configurations +#RUN rm -Rf /etc/rhsm /etc/pki/entitlement + diff --git a/docker/Dockerfile.ran.rhel8.2 b/docker/Dockerfile.ran.rhel8.2 new file mode 100644 index 0000000000..2e4bd586bf --- /dev/null +++ b/docker/Dockerfile.ran.rhel8.2 @@ -0,0 +1,65 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 +# +#--------------------------------------------------------------------- + + +FROM registry.access.redhat.com/ubi8/ubi:latest AS ran-build +ARG NEEDED_GIT_PROXY + +COPY tmp/ca/redhat-uep.pem /etc/rhsm/ca +COPY tmp/entitlement/*.pem /etc/pki/entitlement + +#install developers pkg/repo +RUN rm -f /etc/rhsm-host && \ + yum repolist --disablerepo=* && \ + subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms && \ + yum update -y && \ + yum install -y \ + #gcc needed for build_oai + gcc gcc-c++ \ + diffutils \ + file \ + psmisc \ + git \ + #unzip is needed for protobuf + unzip && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +# In some network environments, GIT proxy is required +RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" + +#create the WORKDIR +WORKDIR /oai-ran +COPY . . + +#run build_oai -I to get the builder image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -I -w USRP + +RUN rm /etc/pki/entitlement/*pem diff --git a/docker/Dockerfile.ran.rhel8.2.oc4-4 b/docker/Dockerfile.ran.rhel8.2.oc4-4 new file mode 100644 index 0000000000..127d66fccb --- /dev/null +++ b/docker/Dockerfile.ran.rhel8.2.oc4-4 @@ -0,0 +1,74 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for RHEL8 in the OpenShift context (v4.4) +# +#--------------------------------------------------------------------- + + +FROM registry.access.redhat.com/ubi8/ubi:latest AS ran-build + +# Entitlements and RHSM configurations are Open-Shift Secret and ConfigMaps +# It is pre-requisite +RUN rm -Rf /etc/rhsm/ca /etc/pki/entitlement +# Copy the entitlements +COPY ./etc-pki-entitlement /etc/pki/entitlement +# Copy the subscription manager configurations +COPY ./rhsm-conf /etc/rhsm +COPY ./rhsm-ca /etc/rhsm/ca + +#install developers pkg/repo +RUN rm /etc/rhsm-host && \ + # Initialize /etc/yum.repos.d/redhat.repo + # See https://access.redhat.com/solutions/1443553 + yum repolist --disablerepo=* && \ + subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms && \ + yum update -y && \ + yum install -y \ + #gcc needed for build_oai + gcc gcc-c++ \ + diffutils \ + file \ + psmisc \ + git \ + #unzip is needed for protobuf + unzip && \ + echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \ + echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf + +# In some network environments, GIT proxy is required +RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" + +#create the WORKDIR +WORKDIR /oai-ran +COPY . . + +#run build_oai -I to get the builder image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -I -w USRP + +#as the image is public, we need to remove the subscription certificates +RUN rm -Rf /etc/pki/entitlement/*.pem + diff --git a/docker/Dockerfile.ran.ubuntu18 b/docker/Dockerfile.ran.ubuntu18 new file mode 100644 index 0000000000..730366da74 --- /dev/null +++ b/docker/Dockerfile.ran.ubuntu18 @@ -0,0 +1,59 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +# Dockerfile for the Open-Air-Interface BUILD service +# Valid for Ubuntu 18.04 +# +#--------------------------------------------------------------------- + + +FROM ubuntu:bionic AS ran-build +ARG NEEDED_GIT_PROXY +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +#install developers pkg/repo +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \ + DEBIAN_FRONTEND=noninteractive apt-get install --yes \ + #gcc needed for build_oai + build-essential \ + psmisc \ + git \ + xxd \ + #unzip is needed for protobuf + unzip + +# In some network environments, GIT proxy is required +RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" + +#create the WORKDIR +WORKDIR /oai-ran +COPY . . + +#run build_oai -I to get the builder image +RUN /bin/sh oaienv && \ + cd cmake_targets && \ + mkdir -p log && \ + ./build_oai -I -w USRP + diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000000..3966196bb1 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,153 @@ + + + + + +
+ + + + + + OAI Docker/Podman Build and Usage Procedures +
+ +--- + +**Table of Contents** + +1. [Build Strategy](#1-build-strategy) +2. [File organization](#2-file-organization) +3. [Building using docker under Ubuntu 18.04](#3-building-using-docker-under-ubuntu-1804) +4. [Building using podman under Red Hat Entreprise Linux 8.2](#4-building-using-podman-under-red-hat-entreprise-linux-82) +5. [Running modems using docker under Ubuntu 18.04](#5-running-modems-using-docker-under-ubuntu-1804) +6. [Running modems using podman under Red Hat Entreprise Linux 8.2](#6-running-modems-using-podman-under-red-hat-entreprise-linux-82) + +--- + +# 1. Build Strategy # + +For all platforms, the strategy for building docker/podman images is the same: + +* First we create a common shared image that contains: + - the latest source files (by using the `COPY` function) + - all the means to build an OAI RAN executable + * all packages, compilers, ... + * especially UHD is installed +* Then from this shared image (`ran-build`) we can build target images for: + - eNB + - gNB + - lte-UE + - nr-UE +* These target images will only contain: + - the generated executable (for example `lte-softmodem.Rel15`) + - the generated shared libraries (for example `liboai_usrpdevif.so.Rel15`) + - the needed libraries and packages to run these generated binaries + - Some configuration file templates + - Some tools (such as `ping`, `ifconfig`) + +TO DO: + +- Proper entrypoints +- Proper port exposure +- ... + +# 2. File organization # + +Dockerfiles are named with the following naming convention: `Dockerfile.${target}.${OS-version}.${cluster-version}` + +Targets can be: + +- `ran` for an image named `ran-build` (the shared image) +- `eNB` for an image named `oai-enb` +- `gNB` for an image named `oai-gnb` +- `lteUE` for an image named `oai-lte-ue` +- `nrUE` for an image named `oai-nr-ue` + +The currently-supported OS are: + +- `rhel8.2` for Red Hat Entreprise Linux +- `ubuntu18` for Ubuntu 18.04 LTS + +The currently-supported cluster version is: + +- `rhel8.2.oc4-4` + +We have also `rhel7.oc4-4` support but it will be discontinued soon. + +For more details in build within a Openshift Cluster, see [OpenShift README](../openshift/README.md) for more details. + +# 3. Building using `docker` under Ubuntu 18.04 # + +## 3.1. Pre-requisites ## + +* `git` installed +* `docker-ce` installed +* Pulling `ubuntu:bionic` from DockerHub + +## 3.2. Building the shared image ## + +This can be done starting `2020.w41` tag on the `develop` branch, or any branch that includes that tag. + +```bash +git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git +cd openairinterface5g +git checkout develop +``` + +In our Eurecom/OSA environment we need to pass a GIT proxy. + +```bash +docker build --target ran-build --tag ran-build:latest --file docker/Dockerfile.ran.ubuntu18 --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . +``` + +if you don't need it, do NOT pass any value: + +```bash +docker build --target ran-build --tag ran-build:latest --file docker/Dockerfile.ran.ubuntu18 . +``` + +After a while: + +```bash +docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +ran-build latest ccb721bc0b57 1 minute ago 4.06GB +... +``` + +## 3.3. Building any target image ## + +For example, the eNB: + +```bash +docker build --target oai-enb --tag oai-enb:latest --file docker/Dockerfile.eNB.ubuntu18 . +``` + +After a while: + +``` +docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +oai-enb latest 25ddbd8b7187 1 minute ago 516MB + 875ea3b05b60 8 minutes ago 8.18GB +ran-build latest ccb721bc0b57 1 hour ago 4.06GB +``` + +Do not forget to remove the temporary image: + +``` +docker image prune --force +``` + +# 4. Building using `podman` under Red Hat Entreprise Linux 8.2 # + +TODO. + +# 5. Running modems using `docker` under Ubuntu 18.04 # + +TODO. + +# 6. Running modems using `podman` under Red Hat Entreprise Linux 8.2 # + +TODO. diff --git a/docker/scripts/enb_entrypoint.sh b/docker/scripts/enb_entrypoint.sh new file mode 100755 index 0000000000..31d99b2a67 --- /dev/null +++ b/docker/scripts/enb_entrypoint.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -euo pipefail + +# Based another env var, pick one template to use +if [[ -v USE_FDD_CU ]]; then ln -s /opt/oai-enb/etc/cu.fdd.conf /opt/oai-enb/etc/enb.conf; fi +if [[ -v USE_FDD_DU ]]; then ln -s /opt/oai-enb/etc/du.fdd.conf /opt/oai-enb/etc/enb.conf; fi +if [[ -v USE_FDD_MONO ]]; then ln -s /opt/oai-enb/etc/enb.fdd.conf /opt/oai-enb/etc/enb.conf; fi +if [[ -v USE_TDD_MONO ]]; then ln -s /opt/oai-enb/etc/enb.tdd.conf /opt/oai-enb/etc/enb.conf; fi +if [[ -v USE_FDD_RCC ]]; then ln -s /opt/oai-enb/etc/rcc.if4p5.enb.fdd.conf /opt/oai-enb/etc/enb.conf; fi +if [[ -v USE_FDD_RRU ]]; then ln -s /opt/oai-enb/etc/rru.fdd.conf /opt/oai-enb/etc/enb.conf; fi +if [[ -v USE_TDD_RRU ]]; then ln -s /opt/oai-enb/etc/rru.tdd.conf /opt/oai-enb/etc/enb.conf; fi + +# Only this template will be manipulated +CONFIG_FILES=`ls /opt/oai-enb/etc/enb.conf` + +for c in ${CONFIG_FILES}; do + # grep variable names (format: ${VAR}) from template to be rendered + VARS=$(grep -oP '@[a-zA-Z0-9_]+@' ${c} | sort | uniq | xargs) + + # create sed expressions for substituting each occurrence of ${VAR} + # with the value of the environment variable "VAR" + EXPRESSIONS="" + for v in ${VARS}; do + NEW_VAR=`echo $v | sed -e "s#@##g"` + if [[ "${!NEW_VAR}x" == "x" ]]; then + echo "Error: Environment variable '${NEW_VAR}' is not set." \ + "Config file '$(basename $c)' requires all of $VARS." + exit 1 + fi + EXPRESSIONS="${EXPRESSIONS};s|${v}|${!NEW_VAR}|g" + done + EXPRESSIONS="${EXPRESSIONS#';'}" + + # render template and inline replace config file + sed -i "${EXPRESSIONS}" ${c} +done + +# Load the USRP binaries +if [[ -v USE_B2XX ]]; then + /usr/lib/uhd/utils/uhd_images_downloader.py -t b2xx +elif [[ -v USE_X3XX ]]; then + /usr/lib/uhd/utils/uhd_images_downloader.py -t x3xx +elif [[ -v USE_N3XX ]]; then + /usr/lib/uhd/utils/uhd_images_downloader.py -t n3xx +fi + +echo "==================================" +echo "== Starting eNB soft modem" +if [[ -v USE_ADDITIONAL_OPTIONS ]]; then + echo "Additional option(s): ${USE_ADDITIONAL_OPTIONS}" + new_args=() + while [[ $# -gt 0 ]]; do + new_args+=("$1") + shift + done + for word in ${USE_ADDITIONAL_OPTIONS}; do + new_args+=("$word") + done + echo "${new_args[@]}" + exec "${new_args[@]}" +else + echo "$@" + exec "$@" +fi diff --git a/docker/scripts/enb_parameters.yaml b/docker/scripts/enb_parameters.yaml new file mode 100644 index 0000000000..a60fc20e29 --- /dev/null +++ b/docker/scripts/enb_parameters.yaml @@ -0,0 +1,248 @@ +#/* +# * 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 +# */ + +--- +- paths: + source_dir: "ci-scripts/conf_files/" + dest_dir: docker/etc + +- configurations: + - filePrefix: cu + outputfilename: "cu.fdd.conf" + config: + - key: Active_eNBs + env: "@ENB_NAME@" + - key: eNB_name + env: "@ENB_NAME@" + - key: plmn_list + env: + mcc: "@MCC@" + mnc: "@MNC@" + mnc_length: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: local_s_if_name + env: "@F1_IF_NAME@" + - key: remote_s_address + env: "@F1_DU_IP_ADDRESS@" + - key: local_s_address + env: "@F1_CU_IP_ADDRESS@" + - key: eutra_band + env: "@UTRA_BAND_ID@" + - key: downlink_frequency + env: "@DL_FREQUENCY_IN_MHZ@000000" + - key: uplink_frequency_offset + env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000" + - key: Nid_cell + env: "@NID_CELL@" + - key: N_RB_DL + env: "@NB_PRB@" + - key: ipv4 + env: "@MME_S1C_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1_MME + env: "@S1C_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1_MME + env: "@F1_CU_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1U + env: "@S1U_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1U + env: "@F1_CU_IP_ADDRESS@" + - key: ENB_IPV4_ADDRESS_FOR_X2C + env: "@F1_CU_IP_ADDRESS@" + + - filePrefix: du + outputfilename: "du.fdd.conf" + config: + - key: Active_eNBs + env: "@ENB_NAME@" + - key: eNB_name + env: "@ENB_NAME@" + - key: plmn_list + env: + mcc: "@MCC@" + mnc: "@MNC@" + mnc_length: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: local_n_if_name + env: "@F1_IF_NAME@" + - key: remote_n_address + env: "@F1_DU_IP_ADDRESS@" + - key: local_n_address + env: "@F1_CU_IP_ADDRESS@" + - key: eutra_band + env: "@UTRA_BAND_ID@" + - key: downlink_frequency + env: "@DL_FREQUENCY_IN_MHZ@000000" + - key: uplink_frequency_offset + env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000" + - key: Nid_cell + env: "@NID_CELL@" + - key: N_RB_DL + env: "@NB_PRB@" + + - filePrefix: rru.fdd + outputfilename: "rru.fdd.conf" + config: + - key: local_if_name + env: "@RRU_IF4P5_IF_NAME@" + - key: remote_address + env: "@RCC_REMOTE_IP_ADDRESS@" + - key: local_address + env: "@RRU_LOCAL_IP_ADDRESS@" + - key: bands + env: "@UTRA_BAND_ID@" + + - filePrefix: rru.tdd + outputfilename: "rru.tdd.conf" + config: + - key: local_if_name + env: "@RRU_IF4P5_IF_NAME@" + - key: remote_address + env: "@RCC_REMOTE_IP_ADDRESS@" + - key: local_address + env: "@RRU_LOCAL_IP_ADDRESS@" + - key: bands + env: "@UTRA_BAND_ID@" + + - filePrefix: enb.band7.tm1.25PRB.usrpb210 + outputfilename: "enb.fdd.conf" + config: + - key: Active_eNBs + env: "@ENB_NAME@" + - key: eNB_name + env: "@ENB_NAME@" + - key: plmn_list + env: + mcc: "@MCC@" + mnc: "@MNC@" + mnc_length: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: eutra_band + env: "@UTRA_BAND_ID@" + - key: downlink_frequency + env: "@DL_FREQUENCY_IN_MHZ@000000" + - key: uplink_frequency_offset + env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000" + - key: Nid_cell + env: "@NID_CELL@" + - key: N_RB_DL + env: "@NB_PRB@" + - key: ipv4 + env: "@MME_S1C_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1_MME + env: "@ENB_S1C_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1_MME + env: "@ENB_S1C_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1U + env: "@ENB_S1U_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1U + env: "@ENB_S1U_IP_ADDRESS@" + - key: ENB_IPV4_ADDRESS_FOR_X2C + env: "@ENB_X2_IP_ADDRESS@" + - key: FLEXRAN_ENABLED + env: "@FLEXRAN_ENABLED@" + - key: FLEXRAN_INTERFACE_NAME + env: "@FLEXRAN_INTERFACE_NAME@" + - key: FLEXRAN_IPV4_ADDRESS + env: "@FLEXRAN_IPV4_ADDRESS@" + + - filePrefix: enb.band40.tm1.25PRB.FairScheduler.usrpb210 + outputfilename: "enb.tdd.conf" + config: + - key: Active_eNBs + env: "@ENB_NAME@" + - key: eNB_name + env: "@ENB_NAME@" + - key: plmn_list + env: + mcc: "@MCC@" + mnc: "@MNC@" + mnc_length: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: eutra_band + env: "@UTRA_BAND_ID@" + - key: downlink_frequency + env: "@DL_FREQUENCY_IN_MHZ@000000" + - key: uplink_frequency_offset + env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000" + - key: Nid_cell + env: "@NID_CELL@" + - key: N_RB_DL + env: "@NB_PRB@" + - key: ipv4 + env: "@MME_S1C_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1_MME + env: "@S1C_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1_MME + env: "@F1_CU_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1U + env: "@S1U_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1U + env: "@F1_CU_IP_ADDRESS@" + - key: ENB_IPV4_ADDRESS_FOR_X2C + env: "@F1_CU_IP_ADDRESS@" + + - filePrefix: "rcc.band7.tm1.nfapi" + outputfilename: "rcc.if4p5.enb.fdd.conf" + config: + - key: Active_eNBs + env: "@ENB_NAME@" + - key: eNB_name + env: "@ENB_NAME@" + - key: plmn_list + env: + mcc: "@MCC@" + mnc: "@MNC@" + mnc_length: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: local_s_if_name + env: "@F1_IF_NAME@" + - key: remote_s_address + env: "@F1_DU_IP_ADDRESS@" + - key: local_s_address + env: "@F1_CU_IP_ADDRESS@" + - key: eutra_band + env: "@UTRA_BAND_ID@" + - key: downlink_frequency + env: "@DL_FREQUENCY_IN_MHZ@000000" + - key: uplink_frequency_offset + env: "@UL_FREQUENCY_OFFSET_IN_MHZ@000000" + - key: Nid_cell + env: "@NID_CELL@" + - key: N_RB_DL + env: "@NB_PRB@" + - key: ipv4 + env: "@MME_S1C_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1_MME + env: "@S1C_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1_MME + env: "@F1_CU_IP_ADDRESS@" + - key: ENB_INTERFACE_NAME_FOR_S1U + env: "@S1U_IF_NAME@" + - key: ENB_IPV4_ADDRESS_FOR_S1U + env: "@F1_CU_IP_ADDRESS@" + - key: ENB_IPV4_ADDRESS_FOR_X2C + env: "@F1_CU_IP_ADDRESS@" + diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py new file mode 100644 index 0000000000..4949e9cf21 --- /dev/null +++ b/docker/scripts/generateTemplate.py @@ -0,0 +1,89 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- + +#----------------------------------------------------------- +# Import +#----------------------------------------------------------- +import re +import yaml +import os +import sys + + +def main(): + #read yaml input parameters + f = open(f'{sys.argv[1]}',) + data = yaml.full_load(f) + dir = os.listdir(f'{data[0]["paths"]["source_dir"]}') + + + #identify configs, read and replace corresponding values + for config in data[1]["configurations"]: + filePrefix = config["filePrefix"] + outputfilename = config["outputfilename"] + for inputfile in dir: + if inputfile.find(filePrefix) >=0: + prefix_outputfile = {"cu": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "du": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "rru.fdd": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "rru.tdd": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "enb.band7.tm1.25PRB.usrpb210": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "enb.band40.tm1.25PRB.FairScheduler.usrpb210": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "rcc.band7.tm1.nfapi": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}' + } + if filePrefix in prefix_outputfile: + outputfile1 = prefix_outputfile[filePrefix] + + directory = f'{data[0]["paths"]["dest_dir"]}' + if not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + + with open(f'{data[0]["paths"]["source_dir"]}{inputfile}', mode='r') as inputfile, \ + open(outputfile1, mode='w') as outputfile: + for line in inputfile: + count = 0 + for key in config["config"]: + if line.find(key["key"]) >= 0: + count += 1 + if re.search(r'preference', line): + templine = line + elif re.search(r'plmn_list', line): + templine = re.sub(r'[0-9]+', '""', line) + templine = re.sub(r'\"\"', key["env"]["mcc"], templine, 1) + templine = re.sub(r'\"\"', key["env"]["mnc"], templine, 1) + templine = re.sub(r'\"\"', key["env"]["mnc_length"], templine, 1) + elif re.search('downlink_frequency', line): + templine = re.sub(r'[0-9]+', key["env"], line) + elif re.search('uplink_frequency_offset', line): + templine = re.sub(r'[0-9]+', key["env"], line) + + elif re.search(r'"(.*?)"', line): + templine = re.sub(r'(?<=")[^"]*(?=")', key["env"], line) + elif re.search(r'[0-9]', line): + templine = re.sub(r'\d+', key["env"], line) + outputfile.write(templine) + + if count == 0: + outputfile.write(line) + +if __name__ == "__main__": + main() diff --git a/executables/main-fs6.c b/executables/main-fs6.c index c4a0d85b34..5283ce5eaa 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -179,7 +179,7 @@ void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_r ru=eNB->RU_list[i]; for (ru_aa=0,aa=0; ru_aanb_rx; ru_aa++,aa++) { - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa]; int ce_level; for (ce_level=0; ce_level<4; ce_level++) @@ -435,7 +435,7 @@ void pusch_procedures_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eN if ((ulsch) && (ulsch->rnti>0) && (ulsch_harq->status == ACTIVE) && - ((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) && + ((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 @@ -1520,7 +1520,7 @@ void *cu_fs6(void *arg) { remoteIP[i]=0; break; } - + AssertFatal(createUDPsock(NULL, CU_PORT, remoteIP, port_def, &sockFS6), ""); L1_rxtx_proc_t L1proc= {0}; // We pick the global thread pool from the legacy code global vars diff --git a/executables/main-ocp.c b/executables/main-ocp.c index cd221b155a..39e7b558ac 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -78,9 +78,18 @@ int otg_enabled; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int split73; +int usrp_tx_thread = 0; char * split73_config; int split73; -int usrp_tx_thread = 0; +AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0}; +AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]= {0}; +void flexran_agent_slice_update(mid_t module_idP) { +} +int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p){ + return 0; +} +void proto_agent_stop(mod_id_t mod_id){ +} static void *ru_thread( void *param ); void kill_RU_proc(RU_t *ru) { @@ -101,21 +110,6 @@ void exit_function(const char *file, const char *function, const int line, const close_log_mem(); oai_exit = 1; - if (RC.ru == NULL) - exit(-1); // likely init not completed, prevent crash or hang, exit now... - - for (int ru_id=0; ru_idrfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - - if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } - sleep(1); //allow lte-softmodem threads to exit first exit(1); } @@ -228,7 +222,7 @@ void init_eNB_afterRU(void) { for (int i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i]; for (int ce_level=0; ce_level<4; ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; @@ -399,6 +393,7 @@ int setup_RU_buffers(RU_t *ru) { return(0); } +#if 0 void init_precoding_weights(PHY_VARS_eNB *eNB) { int layer,ru_id,aa,re,ue,tb; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; @@ -431,6 +426,7 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) { } } } +#endif void ocp_rx_prach(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, @@ -483,7 +479,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int br_flag) ru=eNB->RU_list[i]; for (ru_aa=0,aa=0; ru_aanb_rx; ru_aa++,aa++) { - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa]; int ce_level; if (br_flag==1) @@ -804,8 +800,7 @@ int init_rf(RU_t *ru) { return ret; } -void init_RU(char *rf_config_file, int send_dmrssync) { - RU_t *ru; +void ocp_init_RU(RU_t *ru, char *rf_config_file, int send_dmrssync) { PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; int i; int CC_id; @@ -821,11 +816,8 @@ void init_RU(char *rf_config_file, int send_dmrssync) { LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - for (int ru_id=0; ru_idrf_config_file = rf_config_file; - ru->idx = ru_id; + ru->idx = 0; ru->ts_offset = 0; if (ru->is_slave == 1) { @@ -849,8 +841,6 @@ void init_RU(char *rf_config_file, int send_dmrssync) { ru->wakeup_L1_sleep_cnt_max = 3; if (ru->num_eNB > 0) { - LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", - __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); AssertFatal(ru->eNB_list[0], "ru->eNB_list is not initialized\n"); } else { LOG_E(PHY,"Wrong data model, assigning eNB 0, carrier 0 to RU 0\n"); @@ -867,20 +857,19 @@ void init_RU(char *rf_config_file, int send_dmrssync) { int ruIndex=eNB0->num_RU++; eNB0->RU_list[ruIndex] = ru; } - } // for ru_id } void stop_RU(int nb_ru) { for (int inst = 0; inst < nb_ru; inst++) { LOG_I(PHY, "Stopping RU %d processing threads\n", inst); - kill_RU_proc(RC.ru[inst]); + //kill_RU_proc(RC.ru[inst]); } } /* --------------------------------------------------------*/ /* from here function to use configuration module */ static int DEFBFW[] = {0x00007fff}; -void RCconfig_RU(void) { +void ocpRCconfig_RU(RU_t* ru) { paramdef_t RUParams[] = RUPARAMS_DESC; paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL); @@ -891,87 +880,74 @@ void RCconfig_RU(void) { return; } // setting != NULL - if ( RC.ru != NULL ) { - LOG_W(PHY, "Calling RCconfig_RU twice (nb ru=%d), ignoring the second call data structure is %p\n", - RUParamList.numelt,RC.ru); - return; + ru->idx = 0; + ru->if_timing = synch_to_ext_device; + paramdef_t *vals=RUParamList.paramarray[0]; + + if (RC.nb_L1_inst >0) + ru->num_eNB = vals[RU_ENB_LIST_IDX].numelt; + else + ru->num_eNB = 0; + + for (int i=0; inum_eNB; i++) + ru->eNB_list[i] = RC.eNB[vals[RU_ENB_LIST_IDX].iptr[i]][0]; + + if (config_isparamset(vals, RU_SDR_ADDRS)) { + ru->openair0_cfg.sdr_addrs = strdup(*(vals[RU_SDR_ADDRS].strptr)); } - RC.ru = (RU_t **)malloc(RC.nb_RU*sizeof(RU_t *)); - - for (int j = 0; j < RC.nb_RU; j++) { - RC.ru[j] = (RU_t *)calloc(sizeof(RU_t), 1); - RC.ru[j]->idx = j; - LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]); - RC.ru[j]->if_timing = synch_to_ext_device; - paramdef_t *vals=RUParamList.paramarray[j]; - - if (RC.nb_L1_inst >0) - RC.ru[j]->num_eNB = vals[RU_ENB_LIST_IDX].numelt; - else - RC.ru[j]->num_eNB = 0; - - for (int i=0; inum_eNB; i++) - RC.ru[j]->eNB_list[i] = RC.eNB[vals[RU_ENB_LIST_IDX].iptr[i]][0]; - - if (config_isparamset(vals, RU_SDR_ADDRS)) { - RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(vals[RU_SDR_ADDRS].strptr)); - } - - if (config_isparamset(vals, RU_SDR_CLK_SRC)) { - char *paramVal=*(vals[RU_SDR_CLK_SRC].strptr); - LOG_D(PHY, "RU clock source set as %s\n", paramVal); - - if (strcmp(paramVal, "internal") == 0) { - RC.ru[j]->openair0_cfg.clock_source = internal; - } else if (strcmp(paramVal, "external") == 0) { - RC.ru[j]->openair0_cfg.clock_source = external; - } else if (strcmp(paramVal, "gpsdo") == 0) { - RC.ru[j]->openair0_cfg.clock_source = gpsdo; - } else { - LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", paramVal); - } - } - - if (strcmp(*(vals[RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(vals,RU_LOCAL_IF_NAME_IDX)) ) { - RC.ru[j]->if_south = LOCAL_RF; - RC.ru[j]->function = eNodeB_3GPP; - LOG_I(PHY, "Setting function for RU %d to eNodeB_3GPP\n",j); - } else { - RC.ru[j]->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); - } - - RC.ru[j]->max_pdschReferenceSignalPower = *(vals[RU_MAX_RS_EPRE_IDX].uptr);; - RC.ru[j]->max_rxgain = *(vals[RU_MAX_RXGAIN_IDX].uptr); - RC.ru[j]->num_bands = vals[RU_BAND_LIST_IDX].numelt; - /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ - RC.ru[j]->sf_extension = *(vals[RU_SF_EXTENSION_IDX].uptr); - RC.ru[j]->end_of_burst_delay = *(vals[RU_END_OF_BURST_DELAY_IDX].uptr); - - for (int i=0; inum_bands; i++) RC.ru[j]->band[i] = vals[RU_BAND_LIST_IDX].iptr[i]; + if (config_isparamset(vals, RU_SDR_CLK_SRC)) { + char *paramVal=*(vals[RU_SDR_CLK_SRC].strptr); + LOG_D(PHY, "RU clock source set as %s\n", paramVal); + + if (strcmp(paramVal, "internal") == 0) { + ru->openair0_cfg.clock_source = internal; + } else if (strcmp(paramVal, "external") == 0) { + ru->openair0_cfg.clock_source = external; + } else if (strcmp(paramVal, "gpsdo") == 0) { + ru->openair0_cfg.clock_source = gpsdo; } else { - LOG_I(PHY,"RU %d: Transport %s\n",j,*(vals[RU_TRANSPORT_PREFERENCE_IDX].strptr)); - RC.ru[j]->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); - RC.ru[j]->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); - RC.ru[j]->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); - RC.ru[j]->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); - RC.ru[j]->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); - RC.ru[j]->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); + LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", paramVal); + } + } + + if (strcmp(*(vals[RU_LOCAL_RF_IDX].strptr), "yes") == 0) { + if ( !(config_isparamset(vals,RU_LOCAL_IF_NAME_IDX)) ) { + ru->if_south = LOCAL_RF; + ru->function = eNodeB_3GPP; + } else { + ru->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); + ru->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); + ru->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); + ru->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); + ru->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); + ru->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); + ru->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); + } + + ru->max_pdschReferenceSignalPower = *(vals[RU_MAX_RS_EPRE_IDX].uptr);; + ru->max_rxgain = *(vals[RU_MAX_RXGAIN_IDX].uptr); + ru->num_bands = vals[RU_BAND_LIST_IDX].numelt; + /* sf_extension is in unit of samples for 30.72MHz here, has to be scaled later */ + ru->sf_extension = *(vals[RU_SF_EXTENSION_IDX].uptr); + ru->end_of_burst_delay = *(vals[RU_END_OF_BURST_DELAY_IDX].uptr); + + for (int i=0; inum_bands; i++) + ru->band[i] = vals[RU_BAND_LIST_IDX].iptr[i]; + } else { + ru->eth_params.local_if_name = strdup(*(vals[RU_LOCAL_IF_NAME_IDX].strptr)); + ru->eth_params.my_addr = strdup(*(vals[RU_LOCAL_ADDRESS_IDX].strptr)); + ru->eth_params.remote_addr = strdup(*(vals[RU_REMOTE_ADDRESS_IDX].strptr)); + ru->eth_params.my_portc = *(vals[RU_LOCAL_PORTC_IDX].uptr); + ru->eth_params.remote_portc = *(vals[RU_REMOTE_PORTC_IDX].uptr); + ru->eth_params.my_portd = *(vals[RU_LOCAL_PORTD_IDX].uptr); + ru->eth_params.remote_portd = *(vals[RU_REMOTE_PORTD_IDX].uptr); } /* strcmp(local_rf, "yes") != 0 */ - RC.ru[j]->nb_tx = *(vals[RU_NB_TX_IDX].uptr); - RC.ru[j]->nb_rx = *(vals[RU_NB_RX_IDX].uptr); - RC.ru[j]->att_tx = *(vals[RU_ATT_TX_IDX].uptr); - RC.ru[j]->att_rx = *(vals[RU_ATT_RX_IDX].uptr); - }// j=0..num_rus + ru->nb_tx = *(vals[RU_NB_TX_IDX].uptr); + ru->nb_rx = *(vals[RU_NB_RX_IDX].uptr); + ru->att_tx = *(vals[RU_ATT_TX_IDX].uptr); + ru->att_rx = *(vals[RU_ATT_RX_IDX].uptr); return; } @@ -1055,13 +1031,13 @@ void init_pdcp(void) { 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); + //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); + //pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); } } @@ -1080,23 +1056,18 @@ void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { LOG_I(ENB_APP, "sending TERMINATE_MESSAGE from task %s (%d) to task %s (%d)\n", itti_get_task_name(from), from, itti_get_task_name(to), to); MessageDef *msg; - msg = itti_alloc_new_message (from, TERMINATE_MESSAGE); + msg = itti_alloc_new_message (from, 0, TERMINATE_MESSAGE); itti_send_msg_to_task (to, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } int stop_L1L2(module_id_t enb_id) { LOG_W(ENB_APP, "stopping lte-softmodem\n"); - if (!RC.ru) { - LOG_UI(ENB_APP, "no RU configured\n"); - return -1; - } - /* these tasks need to pick up new configuration */ terminate_task(enb_id, TASK_ENB_APP, TASK_RRC_ENB); oai_exit = 1; LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id); - kill_RU_proc(RC.ru[enb_id]); + //kill_RU_proc(RC.ru[enb_id]); LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id); kill_eNB_proc(enb_id); oai_exit = 0; @@ -1106,7 +1077,7 @@ int stop_L1L2(module_id_t enb_id) { phy_free_lte_eNB(RC.eNB[enb_id][cc_id]); } - phy_free_RU(RC.ru[enb_id]); + //phy_free_RU(RC.ru[enb_id]); free_lte_top(); return 0; } @@ -1115,14 +1086,18 @@ int stop_L1L2(module_id_t enb_id) { * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2() */ int restart_L1L2(module_id_t enb_id) { - RU_t *ru = RC.ru[enb_id]; + RU_t *ru = NULL; //RC.ru[enb_id]; MessageDef *msg_p = NULL; LOG_W(ENB_APP, "restarting lte-softmodem\n"); /* block threads */ pthread_mutex_lock(&sync_mutex); sync_var = -1; pthread_mutex_unlock(&sync_mutex); - RC.ru_mask |= (1 << ru->idx); + + /* copy the changed frame parameters to the RU */ + /* TODO this should be done for all RUs associated to this eNB */ + memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); + /* reset the list of connected UEs in the MAC, since in this process with * loose all UEs (have to reconnect) */ init_UE_info(&RC.mac[enb_id]->UE_info); @@ -1132,14 +1107,9 @@ int restart_L1L2(module_id_t enb_id) { itti_mark_task_ready(TASK_RRC_ENB); /* pass a reconfiguration request which will configure everything down to * RC.eNB[i][j]->frame_parms, too */ - msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + msg_p = itti_alloc_new_message(TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - /* TODO XForms might need to be restarted, but it is currently (09/02/18) - * broken, so we cannot test it */ - init_RU_proc(ru); - ru->rf_map.card = 0; - ru->rf_map.chain = 0; /* CC_id + chain_offset;*/ init_eNB_afterRU(); printf("Sending sync to all threads\n"); pthread_mutex_lock(&sync_mutex); @@ -1171,7 +1141,7 @@ int main ( int argc, char **argv ) { if (opp_enabled ==1) reset_opp_meas(); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); init_opt(); #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" @@ -1187,10 +1157,16 @@ int main ( int argc, char **argv ) { RCconfig_L1(); } + // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. + // but RU thread deals with pre_scd and this is necessary in VNF and simulator. + // some initialization is necessary and init_ru_vnf do this. + RU_t ru; + + /* We need to read RU configuration before FlexRAN starts so it knows what * splits to report. Actual RU start comes later. */ - if (RC.nb_RU > 0 && NFAPI_MODE != NFAPI_MODE_VNF) { - RCconfig_RU(); + if ( NFAPI_MODE != NFAPI_MODE_VNF) { + ocpRCconfig_RU(&ru); LOG_I(PHY, "number of L1 instances %d, number of RU %d, number of CPU cores %d\n", RC.nb_L1_inst, RC.nb_RU, get_nprocs()); @@ -1211,7 +1187,7 @@ int main ( int argc, char **argv ) { if (RC.nb_inst > 0) { /* Start the agent. If it is turned off in the configuration, it won't start */ for (i = 0; i < RC.nb_inst; i++) { - flexran_agent_start(i); + //flexran_agent_start(i); } /* initializes PDCP and sets correct RLC Request/PDCP Indication callbacks @@ -1220,7 +1196,7 @@ int main ( int argc, char **argv ) { AssertFatal(create_tasks(1)==0,"cannot create ITTI tasks\n"); for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) { - MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ); + MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); } @@ -1292,20 +1268,16 @@ int main ( int argc, char **argv ) { printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - // RU thread and some L1 procedure aren't necessary in VNF or L2 FAPI simulator. - // but RU thread deals with pre_scd and this is necessary in VNF and simulator. - // some initialization is necessary and init_ru_vnf do this. + if (RC.nb_RU >0 && NFAPI_MODE!=NFAPI_MODE_VNF) { printf("Initializing RU threads\n"); - init_RU(get_softmodem_params()->rf_config_file, + ocp_init_RU(&ru, + get_softmodem_params()->rf_config_file, get_softmodem_params()->send_dmrs_sync); - for (int ru_id=0; ru_idrf_map.card=0; - RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); - LOG_I(PHY,"Starting ru_thread %d\n",ru_id); - init_RU_proc(RC.ru[ru_id]); - } + ru.rf_map.card=0; + ru.rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); + init_RU_proc(&ru); config_sync_var=0; @@ -1316,6 +1288,7 @@ int main ( int argc, char **argv ) { LOG_I(ENB_APP,"RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init eNBs\n"); + sleep(1); if (NFAPI_MODE!=NFAPI_MODE_PNF && NFAPI_MODE!=NFAPI_MODE_VNF) { LOG_I(ENB_APP,"Not NFAPI mode - call init_eNB_afterRU()\n"); @@ -1369,10 +1342,6 @@ int main ( int argc, char **argv ) { } } - for (int inst = 0; inst < RC.nb_RU; inst++) { - phy_free_RU(RC.ru[inst]); - } - free_lte_top(); end_configmodule(); pthread_cond_destroy(&sync_cond); @@ -1381,17 +1350,6 @@ int main ( int argc, char **argv ) { pthread_mutex_destroy(&nfapi_sync_mutex); pthread_mutex_destroy(&ue_pf_po_mutex); - for(int ru_id=0; ru_idrfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - - if (RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } } terminate_opt(); diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index a48b237845..4a655dfc57 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -48,6 +48,7 @@ #include "SCHED_NR/sched_nr.h" #include "SCHED_NR/fapi_nr_l1.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/MODULATION/nr_modulation.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -71,6 +72,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "enb_config.h" +#include "gnb_paramdef.h" #ifndef OPENAIR2 @@ -100,6 +102,7 @@ extern int transmission_mode; extern uint16_t sf_ahead; extern uint16_t sl_ahead; + //pthread_t main_gNB_thread; time_stats_t softmodem_stats_mt; // main thread @@ -255,11 +258,16 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT // Do PRACH RU processing - int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST); - if (prach_id>=0) { - L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu); - gNB->prach_vars.list[prach_id].frame=-1; - } + L1_nr_prach_procedures(gNB,frame_rx,slot_rx); + + //apply the rx signal rotation here + apply_nr_rotation_ul(&gNB->frame_parms, + gNB->common_vars.rxdataF[0], + slot_rx, + 0, + gNB->frame_parms.Ncp==EXTENDED?12:14, + gNB->frame_parms.ofdm_symbol_size); + phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); } @@ -270,7 +278,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t // run PHY TX procedures the one after the other for all CCs to avoid race conditions // (may be relaxed in the future for performance reasons) // ***************************************** - + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) { @@ -864,7 +872,15 @@ void init_gNB_proc(int inst) { gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t)); gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); - char ul_pool[] = "-1,-1"; + int numCPU = sysconf(_SC_NPROCESSORS_ONLN); + int threadCnt = min(numCPU, gNB->pusch_proc_threads); + char ul_pool[80]; + sprintf(ul_pool,"-1"); + int s_offset = 0; + for (int icpu=1; icputhreadPool, false); initNotifiedFIFO(gNB->respDecode); } @@ -981,7 +997,7 @@ void init_eNB_afterRU(void) { for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa); - gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[i]; + gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i]; gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i]; } } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index a0f5710128..feff0c29c2 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -623,6 +623,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { unsigned int rxs; int i; uint32_t samples_per_slot = fp->get_samples_per_slot(*slot,fp); + uint32_t samples_per_slot_prev ; openair0_timestamp ts,old_ts; AssertFatal(*slotslots_per_frame && *slot>=0, "slot %d is illegal (%d)\n",*slot,fp->slots_per_frame); @@ -658,16 +659,16 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; } else { - if (proc->timestamp_rx - old_ts != fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp)) { - LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot,ru->ts_offset); - ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot); + samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp); + if (proc->timestamp_rx - old_ts != samples_per_slot_prev) { + LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - samples_per_slot_prev,ru->ts_offset); + ru->ts_offset += (proc->timestamp_rx - old_ts - samples_per_slot_prev); proc->timestamp_rx = ts-ru->ts_offset; } } proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; - uint32_t idx_sf = proc->timestamp_rx / fp->samples_per_subframe; - proc->tti_rx = (idx_sf * fp->slots_per_subframe + (int)round((float)(proc->timestamp_rx % fp->samples_per_subframe) / fp->samples_per_slot0))%(fp->slots_per_frame); + proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx,fp); // synchronize first reception to frame 0 subframe 0 LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, @@ -688,7 +689,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { } if (proc->frame_rx != *frame) { - LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame); + LOG_E(PHY,"Received Timestamp (%llu) doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, proc->tti_rx %d, slot %d)\n",(long long unsigned int)proc->timestamp_rx,proc->frame_rx,*frame,proc->tti_rx,*slot); exit_fun("Exiting"); } } else { @@ -727,38 +728,34 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { //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(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++; + if (cfg->cell_config.frame_duplex_type.value == TDD){ + 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); + if(slot%(fp->slots_per_subframe/2)) + siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + 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 } - AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); - if(slot%(fp->slots_per_subframe/2)) - siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); - else - 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 - } + if (slot_type == NR_DOWNLINK_SLOT && prevslot_type == NR_UPLINK_SLOT) + flags = 2; // start of burst - if (cfg->cell_config.frame_duplex_type.value == TDD && - slot_type == NR_DOWNLINK_SLOT && - nextslot_type == NR_UPLINK_SLOT) { - flags = 3; // end of burst + if (slot_type == NR_DOWNLINK_SLOT && nextslot_type == NR_UPLINK_SLOT) + flags = 3; // end of burst } if (fp->freq_range==nr_FR2) { // the beam index is written in bits 8-10 of the flags // bit 11 enables the gpio programming int beam=0; - if (slot==0) beam = 11; //3 for boresight & 8 to enable + //if (slot==0) beam = 11; //3 for boresight & 8 to enable /* if (slot==0 || slot==40) beam=0&8; if (slot==10 || slot==50) beam=1&8; @@ -767,7 +764,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { */ flags |= beam<<8; } - + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); 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 ); @@ -861,9 +858,9 @@ void *ru_thread_prach( void *param ) { if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); + /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 ); - /*if (ru->gNB_list[0]){ + if (ru->gNB_list[0]){ prach_procedures( ru->gNB_list[0],0 ); @@ -1149,19 +1146,22 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { if (ru->if_frequency == 0) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - } - else { + } else if (ru->if_freq_offset){ + cfg->tx_freq[i] = (double)(ru->if_frequency); + cfg->rx_freq[i] = (double)(ru->if_frequency + ru->if_freq_offset); + LOG_I(PHY, "Setting IF TX frequency to %lu Hz with IF RX frequency offset %d Hz\n", ru->if_frequency, ru->if_freq_offset); + } else { cfg->tx_freq[i] = (double)ru->if_frequency; cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); } cfg->tx_gain[i] = ru->att_tx; cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; cfg->configFilename = rf_config_file; - printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", + LOG_I(PHY, "Channel %d: setting tx_gain offset %f, rx_gain offset %f, tx_freq %lu Hz, rx_freq %lu Hz\n", i, cfg->tx_gain[i], cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i]); + (unsigned long)cfg->tx_freq[i], + (unsigned long)cfg->rx_freq[i]); } } @@ -1594,13 +1594,36 @@ void *ru_thread( void *param ) { (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); // Do PRACH RU processing + int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST); + uint8_t prachStartSymbol,N_dur; if (prach_id>=0) { - rx_nr_prach_ru(ru, - ru->prach_list[prach_id].fmt, - ru->prach_list[prach_id].numRA, - ru->prach_list[prach_id].prachStartSymbol, - proc->frame_rx,proc->tti_rx); + N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt); + /* + get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value, + proc->frame_rx,proc->tti_rx, + ru->config.carrier_config.dl_frequency.value, + fp->numerology_index, + fp->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur, + &RA_sfn_index, + &N_RA_slot, + &config_period); + */ + for (int prach_oc = 0; prach_ocprach_list[prach_id].num_prach_ocas; prach_oc++) { + prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur; + //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. + + rx_nr_prach_ru(ru, + ru->prach_list[prach_id].fmt, //could also use format + ru->prach_list[prach_id].numRA, + prachStartSymbol, + prach_oc, + proc->frame_rx,proc->tti_rx); + } free_nr_ru_prach_entry(ru,prach_id); } } @@ -2197,7 +2220,7 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF4p5: ru->do_prach = 0; ru->feprx = NULL; // DFTs - ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // Precoding operation + ru->feptx_prec = 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 @@ -2471,6 +2494,7 @@ void RCconfig_RU(void) 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); RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr); + RC.ru[j]->if_freq_offset = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr); 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; diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index c968fee7b6..500819e684 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -77,6 +77,7 @@ #define CONFIG_HLP_UE "Set the lte softmodem as a UE\n" #define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n" #define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n" +#define CONFIG_HLP_MAC "Disable the MAC procedures at UE side (default is enabled)\n" #define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n" #define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n" #define CONFIG_HLP_TPORT "tracer port\n" diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index a3d0b325d6..d986e98267 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 "executables/thread-common.h" #include "NB_IoT_interface.h" #include "x2ap_eNB.h" +#include "ngap_gNB.h" +#include "gnb_paramdef.h" pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; @@ -298,87 +300,11 @@ void exit_function(const char *file, const char *function, const int line, const } -void *l2l1_task(void *arg) { - MessageDef *message_p = NULL; - int result; - itti_set_task_real_time(TASK_L2L1); - itti_mark_task_ready(TASK_L2L1); - /* Wait for the initialize message */ - printf("Wait for the ITTI initialize message\n"); - - do { - if (message_p != NULL) { - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - - itti_receive_msg (TASK_L2L1, &message_p); - - switch (ITTI_MSG_ID(message_p)) { - case INITIALIZE_MESSAGE: - /* Start gNB thread */ - LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p)); - start_gNB = 1; - break; - - case TERMINATE_MESSAGE: - printf("received terminate message\n"); - oai_exit=1; - start_gNB = 0; - itti_exit_task (); - break; - - default: - LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } - } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE); - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - /* ???? no else but seems to be UE only ??? - do { - // Wait for a message - itti_receive_msg (TASK_L2L1, &message_p); - - switch (ITTI_MSG_ID(message_p)) { - case TERMINATE_MESSAGE: - oai_exit=1; - itti_exit_task (); - break; - - case ACTIVATE_MESSAGE: - start_UE = 1; - break; - - case DEACTIVATE_MESSAGE: - start_UE = 0; - break; - - case MESSAGE_TEST: - LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); - break; - - default: - LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } while(!oai_exit); - */ - return NULL; -} int create_gNB_tasks(uint32_t gnb_nb) { LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); itti_wait_ready(1); - if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { - LOG_E(PDCP, "Create task for L2L1 failed\n"); - return -1; - } if (gnb_nb > 0) { /* Last task to create, others task must be ready before its start */ @@ -387,30 +313,52 @@ int create_gNB_tasks(uint32_t gnb_nb) { return -1; }*/ if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; + LOG_E(SCTP, "Create task for SCTP failed\n"); + return -1; } if (is_x2ap_enabled()) { - if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){ - LOG_E(X2AP, "Create task for X2AP failed\n"); - } + if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){ + LOG_E(X2AP, "Create task for X2AP failed\n"); + } } else { - LOG_I(X2AP, "X2AP is disabled.\n"); + LOG_I(X2AP, "X2AP is disabled.\n"); } } + + paramdef_t NETParams[] = GNBNETPARAMS_DESC; + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) { + for(int i = GNB_INTERFACE_NAME_FOR_NG_AMF_IDX; i <= GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX; i++){ + if( NETParams[i].strptr == NULL){ + LOG_E(NGAP, "No configuration in the file.\n"); + NGAP_CONF_MODE = 0; + } + else { + LOG_D(NGAP, "Configuration in the file: %s.\n",*NETParams[i].strptr); + } + + } + + + if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) { if (gnb_nb > 0) { - /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + /* + if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; } - - if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for S1AP failed\n"); - return -1; - }*/ + */ + if(NGAP_CONF_MODE){ + if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) { + LOG_E(NGAP, "Create task for NGAP failed\n"); + return -1; + } + } else { + LOG_E(NGAP, "Ngap task not created\n"); + } if(!emulate_rf){ @@ -430,9 +378,9 @@ int create_gNB_tasks(uint32_t gnb_nb) { if (gnb_nb > 0) { if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - } + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { @@ -655,7 +603,7 @@ void wait_gNBs(void) { void terminate_task(task_id_t task_id, module_id_t mod_id) { LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); MessageDef *msg; - msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE); itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } @@ -693,7 +641,6 @@ int stop_L1L2(module_id_t gnb_id) { /* these tasks need to pick up new configuration */ terminate_task(TASK_RRC_ENB, gnb_id); - terminate_task(TASK_L2L1, gnb_id); LOG_I(GNB_APP, "calling kill_gNB_proc() for instance %d\n", gnb_id); kill_gNB_proc(gnb_id); LOG_I(GNB_APP, "calling kill_NR_RU_proc() for instance %d\n", gnb_id); @@ -729,16 +676,9 @@ int restart_L1L2(module_id_t gnb_id) { rrc_enb_init(); itti_mark_task_ready(TASK_RRC_ENB); - if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { - LOG_E(PDCP, "Create task for L2L1 failed\n"); - return -1; - } else { - LOG_I(PDCP, "Re-created task for L2L1 successfully\n"); - } - /* pass a reconfiguration request which will configure everything down to * RC.eNB[i][j]->frame_parms, too */ - msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + msg_p = itti_alloc_new_message(TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[gnb_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); /* TODO XForms might need to be restarted, but it is currently (09/02/18) @@ -821,11 +761,15 @@ int main( int argc, char **argv ) } openair0_cfg[0].threequarter_fs = threequarter_fs; - EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; + AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; + NGAP_CONF_MODE = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; if (get_softmodem_params()->do_ra) AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); + if (get_softmodem_params()->sa) + AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n"); + #if T_TRACER T_Config_Init(); #endif @@ -838,9 +782,9 @@ int main( int argc, char **argv ) } cpuf=get_cpu_freq_GHz(); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); // initialize mscgen log after ITTI - MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); + MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); init_opt(); @@ -956,7 +900,7 @@ if(!IS_SOFTMODEM_NOS1) // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init gNBs\n"); if(IS_SOFTMODEM_DOFORMS) { - + sleep(1); scopeParms_t p; p.argc=&argc; p.argv=argv; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index ee61df86e7..6be23582b1 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -18,49 +18,16 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ -#include "executables/thread-common.h" + #include "executables/nr-uesoftmodem.h" - -#include "NR_MAC_UE/mac.h" -//#include "RRC/LTE/rrc_extern.h" -#include "PHY_INTERFACE/phy_interface_extern.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "fapi_nr_ue_l1.h" #include "PHY/phy_extern_nr_ue.h" #include "PHY/INIT/phy_init.h" -#include "PHY/MODULATION/modulation_UE.h" #include "NR_MAC_UE/mac_proto.h" #include "RRC/NR_UE/rrc_proto.h" - #include "SCHED_NR_UE/phy_frame_config_nr.h" #include "SCHED_NR_UE/defs.h" - #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" -#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" - -#ifdef XFORMS - #include "PHY/TOOLS/nr_phy_scope.h" - - extern char do_forms; -#endif - -// Missing stuff? -int next_ra_frame = 0; -module_id_t next_Mod_id = 0; - -extern double cpuf; -//static nfapi_nr_config_request_t config_t; -//static nfapi_nr_config_request_t* config =&config_t; - /* * NR SLOT PROCESSING SEQUENCE * @@ -124,28 +91,22 @@ extern double cpuf; #define DURATION_RX_TO_TX (6) /* For LTE, this duration is fixed to 4 and it is linked to LTE standard for both modes FDD/TDD */ #endif -#define FRAME_PERIOD 100000000ULL -#define DAQ_PERIOD 66667ULL - typedef enum { - pss=0, - pbch=1, - si=2 + pss = 0, + pbch = 1, + si = 2 } sync_mode_t; - void init_nr_ue_vars(PHY_VARS_NR_UE *ue, - NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag) { int nb_connected_gNB = 1, gNB_id; - memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); - ue->Mod_id = UE_id; ue->mac_enabled = 1; + ue->if_inst = nr_ue_if_module_init(0); // Setting UE mode to NOT_SYNCHED by default for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){ @@ -158,6 +119,9 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, // intialize transport init_nr_ue_transport(ue, abstraction_flag); + + // init N_TA offset + init_N_TA_offset(ue); } /*! @@ -175,24 +139,30 @@ static void UE_synch(void *arg) { int i, hw_slot_offset; PHY_VARS_NR_UE *UE = syncD->UE; sync_mode_t sync_mode = pbch; - int CC_id = UE->CC_id; - int freq_offset=0; + //int CC_id = UE->CC_id; + static int freq_offset=0; UE->is_synchronized = 0; if (UE->UE_scan == 0) { - LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %"PRIu64", UL %"PRIu64" (oai_exit %d, rx_num_channels %d)\n", - UE->frame_parms.dl_CarrierFreq, UE->frame_parms.ul_CarrierFreq, - oai_exit, openair0_cfg[0].rx_num_channels); + + #ifdef FR2_TEST + // Overwrite DL frequency (for FR2 testing) + if (downlink_frequency[0][0]!=0){ + UE->frame_parms.dl_CarrierFreq = downlink_frequency[0][0]; + UE->frame_parms.ul_CarrierFreq = downlink_frequency[0][0]; + } + #endif for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq; - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - if (UE->frame_parms.frame_type == FDD) - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_FDD; - else - openair0_cfg[UE->rf_map.card].duplex_mode = duplex_mode_TDD; + LOG_I( PHY, "[SCHED][UE] Check absolute frequency DL %f, UL %f (RF card %d, oai_exit %d, channel %d, rx_num_channels %d)\n", + openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i], + openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i], + UE->rf_map.card, + oai_exit, + i, + openair0_cfg[0].rx_num_channels); + } sync_mode = pbch; @@ -247,31 +217,25 @@ static void UE_synch(void *arg) { case pbch: LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode); - if (nr_initial_sync( &syncD->proc, UE, UE->mode,2) == 0) { + uint64_t dl_carrier, ul_carrier; + double rx_gain_off = 0; + nr_get_carrier_frequencies(&UE->frame_parms, &dl_carrier, &ul_carrier); + + if (nr_initial_sync(&syncD->proc, UE, 2) == 0) { freq_offset = UE->common_vars.freq_offset; // frequency offset computed with pss in initial sync hw_slot_offset = ((UE->rx_offset<<1) / UE->frame_parms.samples_per_subframe * UE->frame_parms.slots_per_subframe) + round((float)((UE->rx_offset<<1) % UE->frame_parms.samples_per_subframe)/UE->frame_parms.samples_per_slot0); - LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %lu, UL %lu), UE_scan_carrier %d\n", - hw_slot_offset, - freq_offset, - UE->rx_total_gain_dB, - UE->frame_parms.dl_CarrierFreq+freq_offset, - UE->frame_parms.ul_CarrierFreq+freq_offset, - UE->UE_scan_carrier ); // rerun with new cell parameters and frequency-offset - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + // todo: the freq_offset computed on DL shall be scaled before being applied to UL + nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset); - if (freq_offset >= 0) - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(freq_offset); - else - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(freq_offset); - - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+(UE->frame_parms.ul_CarrierFreq-UE->frame_parms.dl_CarrierFreq); - UE->frame_parms.dl_CarrierFreq = openair0_cfg[CC_id].rx_freq[i]; - } + LOG_I(PHY,"Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %f (DL %f Hz, UL %f Hz)\n", + hw_slot_offset, + freq_offset, + openair0_cfg[UE->rf_map.card].rx_gain[0], + openair0_cfg[UE->rf_map.card].rx_freq[0], + openair0_cfg[UE->rf_map.card].tx_freq[0]); // reconfigure for potentially different bandwidth switch(UE->frame_parms.N_RB_DL) { @@ -315,7 +279,6 @@ static void UE_synch(void *arg) { //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]); //UE->rfdevice.trx_stop_func(&UE->rfdevice); // sleep(1); - //nr_init_frame_parms_ue(&UE->frame_parms); /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { LOG_E(HW,"Could not start the device\n"); oai_exit=1; @@ -328,31 +291,21 @@ static void UE_synch(void *arg) { UE->is_synchronized = 1; } } else { - // initial sync failed - // calculate new offset and try again + if (UE->UE_scan_carrier == 1) { + if (freq_offset >= 0) freq_offset += 100; freq_offset *= -1; - LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %lu, UL %lu)\n", - freq_offset, - UE->rx_total_gain_dB, - UE->frame_parms.dl_CarrierFreq+freq_offset, - UE->frame_parms.ul_CarrierFreq+freq_offset ); - for (i=0; irf_map.card].rx_num_channels; i++) { - openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = UE->frame_parms.dl_CarrierFreq+freq_offset; - openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = UE->frame_parms.ul_CarrierFreq+freq_offset; - openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET; + nr_rf_card_config(&openair0_cfg[UE->rf_map.card], rx_gain_off, ul_carrier, dl_carrier, freq_offset); - if (UE->UE_scan_carrier==1) - openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1; - } + LOG_I(PHY, "Initial sync failed: trying carrier off %d Hz\n", freq_offset); if (UE->mode != loop_through_memory) UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0); - }// initial_sync=0 + } break; @@ -365,7 +318,7 @@ static void UE_synch(void *arg) { void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { fapi_nr_config_request_t *cfg = &UE->nrUE_config; - int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx); + int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_slot_tx); uint8_t gNB_id = 0; if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){ @@ -380,16 +333,16 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { ul_indication.gNB_index = gNB_id; ul_indication.cc_id = UE->CC_id; ul_indication.frame_rx = proc->frame_rx; - ul_indication.slot_rx = proc->nr_tti_rx; + ul_indication.slot_rx = proc->nr_slot_rx; ul_indication.frame_tx = proc->frame_tx; - ul_indication.slot_tx = proc->nr_tti_tx; + ul_indication.slot_tx = proc->nr_slot_tx; + ul_indication.thread_id = proc->thread_id; UE->if_inst->ul_indication(&ul_indication); } if (UE->mode != loop_through_memory) { - uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_rx]; - phy_procedures_nrUE_TX(UE,proc,0,thread_id); + phy_procedures_nrUE_TX(UE,proc,0); } } } @@ -397,60 +350,34 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { fapi_nr_config_request_t *cfg = &UE->nrUE_config; - int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_tti_rx); + int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_slot_rx); uint8_t gNB_id = 0; if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){ if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) { nr_downlink_indication_t dl_indication; - memset((void*)&dl_indication, 0, sizeof(dl_indication)); - - dl_indication.module_id = UE->Mod_id; - dl_indication.gNB_index = gNB_id; - dl_indication.cc_id = UE->CC_id; - dl_indication.frame = proc->frame_rx; - dl_indication.slot = proc->nr_tti_rx; - + nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id); UE->if_inst->dl_indication(&dl_indication, NULL); } // Process Rx data for one sub-frame #ifdef UE_SLOT_PARALLELISATION - phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL ); + phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL ); #else uint64_t a=rdtsc(); - phy_procedures_nrUE_RX( UE, proc, 0, UE->mode); - LOG_D(PHY,"phy_procedures_nrUE_RX: slot:%d, time %lu\n", proc->nr_tti_rx, (rdtsc()-a)/3500); - //printf(">>> nr_ue_pdcch_procedures ended\n"); + phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel); + LOG_D(PHY, "In %s: slot %d, time %lu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc()-a)/3500); #endif - if(IS_SOFTMODEM_NOS1){ //&& proc->nr_tti_rx==1 - //Hardcoded rnti value + if(IS_SOFTMODEM_NOS1){ + NR_UE_MAC_INST_t *mac = get_mac_inst(0); 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); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, mac->crnti, proc->frame_rx, proc->nr_slot_rx, 0); pdcp_run(&ctxt); } } - // no UL for now - /* - if (UE->mac_enabled==1) { - // trigger L2 to run ue_scheduler thru IF module - // [TODO] mapping right after NR initial sync - if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) { - UE->ul_indication.module_id = 0; - UE->ul_indication.gNB_index = 0; - UE->ul_indication.cc_id = 0; - UE->ul_indication.frame = proc->frame_rx; - UE->ul_indication.slot = proc->nr_tti_rx; - UE->if_inst->ul_indication(&UE->ul_indication); - } - } - */ - } /*! @@ -470,32 +397,13 @@ void UE_processing(void *arg) { processingData_t *rxtxD = (processingData_t *) arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; + int slot_tx = proc->nr_slot_tx; + int frame_tx = proc->frame_tx; processSlotRX(UE, proc); processSlotTX(UE, proc); + ue_ta_procedures(UE, slot_tx, frame_tx); - /* UL time alignment - // If the current tx frame and slot match the TA configuration in ul_time_alignment - // then timing advance is processed and set to be applied in the next UL transmission */ - if (UE->mac_enabled == 1) { - uint8_t gNB_id = 0; - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id]; - int slot_tx = proc->nr_tti_tx; - int frame_tx = proc->frame_tx; - - if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) { - uint8_t numerology = UE->frame_parms.numerology_index; - uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL; - - LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx); - - //if (nfapi_mode!=3){ - nr_process_timing_advance(UE->Mod_id, UE->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB); - ul_time_alignment->ta_frame = -1; - ul_time_alignment->ta_slot = -1; - //} - } - } } void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) { @@ -607,7 +515,7 @@ void *UE_thread(void *arg) { //this thread should be over the processing thread to keep in real time PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0; - openair0_timestamp timestamp; + openair0_timestamp timestamp, writeTimestamp; void *rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX]; int start_rx_stream = 0; AssertFatal(0== openair0_device_load(&(UE->rfdevice), &openair0_cfg[0]), ""); @@ -632,7 +540,7 @@ void *UE_thread(void *arg) { while (!oai_exit) { if (syncRunning) { - notifiedFIFO_elt_t *res=tryPullTpool(&nf, Tpool); + notifiedFIFO_elt_t *res=tryPullTpool(&nf,&(get_nrUE_params()->Tpool)); if (res) { syncRunning=false; @@ -658,7 +566,7 @@ void *UE_thread(void *arg) { syncData_t *syncMsg=(syncData_t *)NotifiedFifoData(Msg); syncMsg->UE=UE; memset(&syncMsg->proc, 0, sizeof(syncMsg->proc)); - pushTpool(Tpool, Msg); + pushTpool(&(get_nrUE_params()->Tpool), Msg); trashed_frames=0; syncRunning=true; continue; @@ -698,14 +606,12 @@ void *UE_thread(void *arg) { processingData_t *curMsg=(processingData_t *)NotifiedFifoData(msgToPush); curMsg->UE=UE; // update thread index for received subframe - curMsg->UE->current_thread_id[slot_nr] = thread_idx; - curMsg->proc.CC_id = UE->CC_id; - curMsg->proc.nr_tti_rx= slot_nr; - curMsg->proc.subframe_rx=slot_nr/(nb_slot_frame/10); - curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; - curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx; - curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER; - curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER; + curMsg->proc.thread_id = thread_idx; + curMsg->proc.CC_id = UE->CC_id; + curMsg->proc.nr_slot_rx = slot_nr; + curMsg->proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; + curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER; + curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER; curMsg->proc.decoded_frame_rx=-1; //LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB); @@ -736,13 +642,7 @@ void *UE_thread(void *arg) { UE->rx_offset_diff = computeSamplesShift(UE); readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- - UE->rx_offset_diff; - } - - if (UE->timing_advance != timing_advance) { - writeBlockSize -= UE->timing_advance - timing_advance; - timing_advance = UE->timing_advance; + writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff; } AssertFatal(readBlockSize == @@ -775,51 +675,73 @@ void *UE_thread(void *arg) { notifiedFIFO_elt_t *res; while (nbSlotProcessing >= RX_NB_TH) { - res=pullTpool(&nf, Tpool); + res=pullTpool(&nf, &(get_nrUE_params()->Tpool)); nbSlotProcessing--; processingData_t *tmp=(processingData_t *)res->msgData; if (tmp->proc.decoded_frame_rx != -1) decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); - //decoded_frame_rx=tmp->proc.decoded_frame_rx; + else + decoded_frame_rx=-1; pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); } - if ( (decoded_frame_rx != curMsg->proc.frame_rx) && - (((decoded_frame_rx+1) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx) && - (((decoded_frame_rx+2) % MAX_FRAME_NUMBER) != curMsg->proc.frame_rx)) + if ( decoded_frame_rx>0 && decoded_frame_rx != curMsg->proc.frame_rx) LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n", decoded_frame_rx, curMsg->proc.frame_rx ); - AssertFatal( writeBlockSize == - UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - UE->frame_parms.get_samples_slot_timestamp(slot_nr, - &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) - firstSymSamp - - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - UE->timing_advance, - txp, - writeBlockSize, - UE->frame_parms.nb_antennas_tx, - 1),""); + // use previous timing_advance value to compute writeTimestamp + writeTimestamp = timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr, &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) - + firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance; + // but use current UE->timing_advance value to compute writeBlockSize + if (UE->timing_advance != timing_advance) { + writeBlockSize -= UE->timing_advance - timing_advance; + timing_advance = UE->timing_advance; + } + + int flags = 0; + int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - RX_NB_TH; + uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; + uint8_t num_UL_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots + + (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0); + uint8_t first_tx_slot = tdd_period - num_UL_slots; + if (slot_tx_usrp%tdd_period==first_tx_slot) + flags=2; + else if (slot_tx_usrp%tdd_period==first_tx_slot+num_UL_slots-1) + flags = 3; + else if (slot_tx_usrp%tdd_period>first_tx_slot) + flags = 1; + + if (flags || IS_SOFTMODEM_RFSIM) + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + writeTimestamp, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + flags),""); + for (int i=0; iframe_parms.nb_antennas_tx; i++) memset(txp[i], 0, writeBlockSize); nbSlotProcessing++; msgToPush->key=slot_nr; - pushTpool(Tpool, msgToPush); + pushTpool(&(get_nrUE_params()->Tpool), msgToPush); - if (IS_SOFTMODEM_RFSIM || IS_SOFTMODEM_NOS1) { //getenv("RFSIMULATOR") + if (IS_SOFTMODEM_RFSIM) { //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 - res=pullTpool(&nf, Tpool); + res=pullTpool(&nf, &(get_nrUE_params()->Tpool)); nbSlotProcessing--; processingData_t *tmp=(processingData_t *)res->msgData; if (tmp->proc.decoded_frame_rx != -1) decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); + else + decoded_frame_rx=-1; //decoded_frame_rx=tmp->proc.decoded_frame_rx; pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); @@ -870,11 +792,11 @@ void init_NR_UE_threads(int nb_inst) { 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); -#ifdef UE_DLSCH_PARALLELISATION - pthread_t dlsch0_threads; - threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1); -#endif - + if(get_nrUE_params()->nr_dlsch_parallel) + { + pthread_t dlsch0_threads; + threadCreate(&dlsch0_threads, dlsch_thread, (void *)UE, "DLthread", -1, OAI_PRIORITY_RT_MAX-1); + } } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index e6d644453c..87cd157948 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -40,9 +40,10 @@ //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all #include "openair1/PHY/MODULATION/nr_modulation.h" #include "PHY/phy_vars_nr_ue.h" -#include "PHY/LTE_TRANSPORT/transport_vars.h" +#include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "SCHED/sched_common_vars.h" #include "PHY/MODULATION/modulation_vars.h" +#include "PHY/NR_TRANSPORT/nr_dlsch.h" //#include "../../SIMU/USER/init_lte.h" #include "LAYER2/MAC/mac_vars.h" @@ -81,11 +82,14 @@ unsigned short config_frames[4] = {2,9,11,13}; // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) #include "PHY/TOOLS/phy_scope_interface.h" #include "PHY/TOOLS/nr_phy_scope.h" +#define NRUE_MAIN #include #include "executables/softmodem-common.h" #include "executables/thread-common.h" -// Raphael : missing +extern const char *duplex_mode[]; + +// Thread variables pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex @@ -95,29 +99,29 @@ pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; + + RAN_CONTEXT_t RC; volatile int start_eNB = 0; volatile int start_UE = 0; volatile int oai_exit = 0; -int single_thread_flag=1; -static double snr_dB=20; -int threequarter_fs=0; +extern int16_t nr_dlsch_demod_shift; +static int tx_max_power[MAX_NUM_CCs] = {0}; -uint64_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -//int32_t uplink_counter = 0; +int single_thread_flag = 1; +int tddflag = 0; +int vcdflag = 0; +double rx_gain_off = 0.0; +char *usrp_args = NULL; +char *rrc_config_path = NULL; +int dumpframe = 0; -extern int16_t nr_dlsch_demod_shift; - -int UE_scan = 0; -int UE_scan_carrier = 0; -int UE_fo_compensation = 0; -int UE_no_timing_correction = 0; -runmode_t mode = normal_txrx; -openair0_config_t openair0_cfg[MAX_CARDS]; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int rx_input_level_dBm; #if MAX_NUM_CCs == 1 rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; @@ -129,74 +133,25 @@ double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; #endif -double rx_gain_off = 0.0; +// UE and OAI config variables -double sample_rate=30.72e6; -double bw = 10.0e6; - -static int tx_max_power[MAX_NUM_CCs] = {0}; +openair0_config_t openair0_cfg[MAX_CARDS]; +int16_t node_synch_ref[MAX_NUM_CCs]; +int otg_enabled; +double cpuf; -int chain_offset=0; - - -uint8_t dci_Format = 0; -uint8_t agregation_Level =0xFF; - -uint8_t nb_antenna_tx = 1; -uint8_t nb_antenna_rx = 1; - -char ref[128] = "internal"; -char channels[128] = "0"; - - -int rx_input_level_dBm; - -//static int online_log_messages=0; - - -int otg_enabled; -//int number_of_cards = 1; - -static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -int16_t node_synch_ref[MAX_NUM_CCs]; - -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; -uint32_t timing_advance = 0; -uint64_t num_missed_slots=0; // counter for the number of missed slots - - -int transmission_mode=1; -int numerology = 0; -int usrp_tx_thread = 0; - -/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */ -//uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD; -/* struct for ethernet specific parameters given in eNB conf file */ -//eth_params_t *eth_params; - -double cpuf; +int chain_offset = 0; +int card_offset = 0; +uint64_t num_missed_slots = 0; // counter for the number of missed slots +int transmission_mode = 1; +int numerology = 0; +int usrp_tx_thread = 0; +int oaisim_flag = 0; +int emulate_rf = 0; char uecap_xer[1024],uecap_xer_in=0; -int oaisim_flag=0; -int emulate_rf = 0; - -tpool_t *Tpool; -#ifdef UE_DLSCH_PARALLELISATION - tpool_t *Tpool_dl; -#endif - - -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]); - - /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution */ @@ -245,160 +200,39 @@ void exit_function(const char *file, const char *function, const int line, const exit(1); } - -void reset_stats(long arg) { - //int i,j,k; - /*PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0]; - - for (i=0; idlsch[i][0]->Mlimit; j++) { - phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; - phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; - phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; - } - - phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; - phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; - phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; - - for (j=0; julsch[i]->Mlimit; j++) { - phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0; - phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0; - } - } - - phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; - phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; - phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; - }*/ +uint64_t get_nrUE_optmask(void) { + return nrUE_params.optmask; } -void *l2l1_task(void *arg) { - MessageDef *message_p = NULL; - int result; - itti_set_task_real_time(TASK_L2L1); - itti_mark_task_ready(TASK_L2L1); - - do { - // Wait for a message - itti_receive_msg (TASK_L2L1, &message_p); - - switch (ITTI_MSG_ID(message_p)) { - case TERMINATE_MESSAGE: - oai_exit=1; - itti_exit_task (); - break; - - case ACTIVATE_MESSAGE: - start_UE = 1; - break; - - case DEACTIVATE_MESSAGE: - start_UE = 0; - break; - - case MESSAGE_TEST: - LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); - break; - - default: - LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } while(!oai_exit); - - return NULL; +uint64_t set_nrUE_optmask(uint64_t bitmask) { + nrUE_params.optmask = nrUE_params.optmask | bitmask; + return nrUE_params.optmask; } - -int16_t dlsch_demod_shift; - +nrUE_params_t *get_nrUE_params(void) { + return &nrUE_params; +} +/* initialie thread pools used for NRUE processing paralleliation */ +void init_tpools(uint8_t nun_dlsch_threads) { + char *params=calloc(1,(RX_NB_TH*3)+1); + for (int i=0; i 0) mode = debug_prach; - - if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) - if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; - - if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) - if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; - - if (dumpframe > 0) mode = rx_dump_frame; - - for (CC_id=0; CC_iddl_CarrierFreq = downlink_frequency[0][0]; - } - - UE_scan=0; - - if (tddflag > 0) { - for (CC_id=0; CC_idframe_type = TDD; - } if (vcdflag > 0) ouput_vcd = 1; - /*if (frame_parms[0]->N_RB_DL !=0) { - if ( frame_parms[0]->N_RB_DL < 6 ) { - frame_parms[0]->N_RB_DL = 6; - printf ( "%i: Invalid number of resource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 100 ) { - frame_parms[0]->N_RB_DL = 100; - printf ( "%i: Invalid number of resource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { - frame_parms[0]->N_RB_DL = 50; - printf ( "%i: Invalid number of resource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); - } - if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { - frame_parms[0]->N_RB_DL = 25; - printf ( "%i: Invalid number of resource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); - } - UE_scan = 0; - frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; - for (CC_id=1; CC_idN_RB_DL=frame_parms[0]->N_RB_DL; - frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; - } - }*/ - - for (CC_id=1; CC_idframe_parms; + paramdef_t cmdline_params[] = CMDLINE_NRUE_PHYPARAMS_DESC ; + int numparams = sizeof(cmdline_params)/sizeof(paramdef_t); -void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { - int CC_id; + UE->mode = normal_txrx; - for (CC_id=0; CC_idnr_band = 78; - frame_parms[CC_id]->frame_type = FDD; - frame_parms[CC_id]->tdd_config = 3; - //frame_parms[CC_id]->tdd_config_S = 0; - frame_parms[CC_id]->N_RB_DL = 106; - frame_parms[CC_id]->N_RB_UL = 106; - frame_parms[CC_id]->Ncp = NORMAL; - //frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms[CC_id]->Nid_cell = 0; - //frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms[CC_id]->nb_antenna_ports_gNB = 1; - frame_parms[CC_id]->nb_antennas_tx = 1; - frame_parms[CC_id]->nb_antennas_rx = 1; - //frame_parms[CC_id]->nushift = 0; - // NR: Init to legacy LTE 20Mhz params - frame_parms[CC_id]->numerology_index = 0; - frame_parms[CC_id]->ttis_per_subframe = 1; - frame_parms[CC_id]->slots_per_tti = 2; + config_process_cmdline( cmdline_params,numparams,NULL); + + int pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRX_OPT); + if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue; + + pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXMED_OPT); + if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_med; + + pindex = config_paramidx_fromname(cmdline_params,numparams, CALIBRXBYP_OPT); + if ( (cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) UE->mode = rx_calib_ue_byp; + + pindex = config_paramidx_fromname(cmdline_params,numparams, DBGPRACH_OPT); + if (cmdline_params[pindex].uptr) + if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = debug_prach; + + pindex = config_paramidx_fromname(cmdline_params,numparams,NOL2CONNECT_OPT ); + if (cmdline_params[pindex].uptr) + if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = no_L2_connect; + + pindex = config_paramidx_fromname(cmdline_params,numparams,CALIBPRACH_OPT ); + if (cmdline_params[pindex].uptr) + if ( *(cmdline_params[pindex].uptr) > 0) UE->mode = calib_prach_tx; + + pindex = config_paramidx_fromname(cmdline_params,numparams,DUMPFRAME_OPT ); + if ((cmdline_params[pindex].paramflags & PARAMFLAG_PARAMSET) != 0) + UE->mode = rx_dump_frame; + + // Init power variables + tx_max_power[CC_id] = tx_max_power[0]; + rx_gain[0][CC_id] = rx_gain[0][0]; + tx_gain[0][CC_id] = tx_gain[0][0]; + + // Set UE variables + UE->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE->tx_total_gain_dB = (int)tx_gain[CC_id][0]; + UE->tx_power_max_dBm = tx_max_power[CC_id]; + UE->rf_map.card = card_offset; + UE->rf_map.chain = CC_id + chain_offset; + + + LOG_I(PHY,"Set UE mode %d, UE_fo_compensation %d, UE_scan_carrier %d, UE_no_timing_correction %d \n", + UE->mode, UE->UE_fo_compensation, UE->UE_scan_carrier, UE->no_timing_correction); + + // Set FP variables + + + + if (tddflag){ + fp->frame_type = TDD; + LOG_I(PHY, "Set UE frame_type %d\n", fp->frame_type); } + + LOG_I(PHY, "Set UE N_RB_DL %d\n", fp->N_RB_DL); + + LOG_I(PHY, "Set UE nb_rx_antenna %d, nb_tx_antenna %d, threequarter_fs %d\n", fp->nb_antennas_rx, fp->nb_antennas_tx, fp->threequarter_fs); + } void init_openair0(void) { int card; - int i; + int freq_off = 0; + NR_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[0][0]->frame_parms; for (card=0; cardthreequarter_fs; - numerology = frame_parms[0]->numerology_index; + openair0_cfg[card].threequarter_fs = frame_parms->threequarter_fs; + numerology = frame_parms->numerology_index; - if(frame_parms[0]->N_RB_DL == 66) { + if(frame_parms->N_RB_DL == 66) { if (numerology==3) { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; @@ -453,7 +328,7 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); exit(-1); } - }else if(frame_parms[0]->N_RB_DL == 32) { + }else if(frame_parms->N_RB_DL == 32) { if (numerology==3) { openair0_cfg[card].sample_rate=61.44e6; openair0_cfg[card].samples_per_frame = 614400; @@ -461,9 +336,9 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology! FR2 supports only 120KHz SCS for now.\n"); exit(-1); } - }else if(frame_parms[0]->N_RB_DL == 217) { + }else if(frame_parms->N_RB_DL == 217) { if (numerology==1) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { openair0_cfg[card].sample_rate=92.16e6; openair0_cfg[card].samples_per_frame = 921600; } @@ -475,9 +350,9 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms[0]->N_RB_DL == 273) { + } else if(frame_parms->N_RB_DL == 273) { if (numerology==1) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); } else { @@ -488,9 +363,9 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms[0]->N_RB_DL == 106) { + } else if(frame_parms->N_RB_DL == 106) { if (numerology==0) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].samples_per_frame = 230400; } else { @@ -498,7 +373,7 @@ void init_openair0(void) { openair0_cfg[card].samples_per_frame = 307200; } } else if (numerology==1) { - if (frame_parms[0]->threequarter_fs) { + if (frame_parms->threequarter_fs) { openair0_cfg[card].sample_rate=46.08e6; openair0_cfg[card].samples_per_frame = 460800; } @@ -513,57 +388,44 @@ void init_openair0(void) { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); } - } else if(frame_parms[0]->N_RB_DL == 50) { + } else if(frame_parms->N_RB_DL == 50) { openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].samples_per_frame = 153600; - } else if (frame_parms[0]->N_RB_DL == 25) { + } else if (frame_parms->N_RB_DL == 25) { openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].samples_per_frame = 76800; - } else if (frame_parms[0]->N_RB_DL == 6) { + } else if (frame_parms->N_RB_DL == 6) { openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].samples_per_frame = 19200; } else { - LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); + LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms->N_RB_DL); exit(-1); } - if (frame_parms[0]->frame_type==TDD) + if (frame_parms->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; - else //FDD + else openair0_cfg[card].duplex_mode = duplex_mode_FDD; - printf("HW: Configuring card %d, nb_antennas_tx/rx %hhu/%hhu\n",card, - PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, - PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); openair0_cfg[card].Mod_id = 0; - openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL; openair0_cfg[card].clock_source = get_softmodem_params()->clock_source; openair0_cfg[card].time_source = get_softmodem_params()->timing_source; - openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx); - openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx); + openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx); - for (i=0; i<4; i++) { - if (iul_CarrierFreq; - else - openair0_cfg[card].tx_freq[i]=0.0; + LOG_I(PHY, "HW: Configuring card %d, tx/rx num_channels %d/%d, duplex_mode %s\n", + card, + openair0_cfg[card].tx_num_channels, + openair0_cfg[card].rx_num_channels, + duplex_mode[openair0_cfg[card].duplex_mode]); - if (idl_CarrierFreq; - else - openair0_cfg[card].rx_freq[i]=0.0; + nr_get_carrier_frequencies(frame_parms, &dl_carrier, &ul_carrier); - openair0_cfg[card].autocal[i] = 1; - openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; - printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", - card,i, openair0_cfg[card].tx_gain[i], - openair0_cfg[card].rx_gain[i], - openair0_cfg[card].tx_freq[i], - openair0_cfg[card].rx_freq[i]); - } + nr_rf_card_config(&openair0_cfg[card], rx_gain_off, ul_carrier, dl_carrier, freq_off); + + openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; if (usrp_args) openair0_cfg[card].sdr_addrs = usrp_args; @@ -607,32 +469,24 @@ int main( int argc, char **argv ) { } set_softmodem_sighandler(); CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - set_default_frame_parms(frame_parms); - mode = normal_txrx; memset(openair0_cfg,0,sizeof(openair0_config_t)*MAX_CARDS); memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); // initialize logging logInit(); // get options and fill parameters from configuration file - get_options (); //Command-line options, enb_properties + + get_options (); //Command-line options specific for NRUE + get_common_options(SOFTMODEM_5GUE_BIT ); + CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); #if T_TRACER T_Config_Init(); #endif //randominit (0); set_taus_seed (0); - tpool_t pool; - Tpool = &pool; - char params[]="-1,-1"; - initTpool(params, Tpool, false); -#ifdef UE_DLSCH_PARALLELISATION - tpool_t pool_dl; - Tpool_dl = &pool_dl; - char params_dl[]="-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"; - initTpool(params_dl, Tpool_dl, false); -#endif + cpuf=get_cpu_freq_GHz(); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); init_opt() ; load_nrLDPClib(); @@ -649,14 +503,6 @@ int main( int argc, char **argv ) { init_NR_UE(1,rrc_config_path); if(IS_SOFTMODEM_NOS1) init_pdcp(); -/* -#ifdef PDCP_USE_NETLINK - netlink_init(); -#if defined(PDCP_USE_NETLINK_QUEUES) - pdcp_netlink_init(); -#endif -#endif -*/ NB_UE_INST=1; NB_INST=1; @@ -666,94 +512,38 @@ int main( int argc, char **argv ) { if (get_softmodem_params()->do_ra) AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); + if (get_softmodem_params()->sa) + AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n"); + for (int CC_id=0; CC_idofdm_symbol_size); - frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; - frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; - frame_parms[CC_id]->nb_antenna_ports_gNB = 1; //initial value overwritten by initial sync later - frame_parms[CC_id]->threequarter_fs = threequarter_fs; - LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); + PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE)); + set_options(CC_id, UE[CC_id]); + NR_UE_MAC_INST_t *mac = get_mac_inst(0); if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL) mac->if_module->phy_config_request(&mac->phy_config); fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; - nr_init_frame_parms_ue(frame_parms[CC_id],nrUE_config,NORMAL); + nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]); + init_symbol_rotation(&UE[CC_id]->frame_parms, UE[CC_id]->frame_parms.dl_CarrierFreq); + init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); + + #ifdef FR2_TEST // Overwrite DL frequency (for FR2 testing) - if (downlink_frequency[0][0]!=0) { + if (downlink_frequency[0][0]!=0){ frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; - frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0]; - } - - init_symbol_rotation(frame_parms[CC_id],frame_parms[CC_id]->dl_CarrierFreq); - init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag); - - UE[CC_id]->mac_enabled = 1; - UE[CC_id]->if_inst = nr_ue_if_module_init(0); - UE[CC_id]->UE_scan = UE_scan; - UE[CC_id]->UE_scan_carrier = UE_scan_carrier; - UE[CC_id]->UE_fo_compensation = UE_fo_compensation; - UE[CC_id]->mode = mode; - UE[CC_id]->no_timing_correction = UE_no_timing_correction; - printf("UE[%d]->mode = %d\n",CC_id,mode); - - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; - UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - - if (UE[CC_id]->frame_parms.frame_type == FDD) { - UE[CC_id]->N_TA_offset = 0; - } else { - int N_RB = UE[CC_id]->frame_parms.N_RB_DL; - int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 - double factor=1; - switch (UE[CC_id]->frame_parms.numerology_index) { - case 0: //15 kHz scs - AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); - if (N_RB <= 25) factor = .25; // 7.68 Ms/s - else if (N_RB <=50) factor = .5; // 15.36 Ms/s - else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s - else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s - else AssertFatal(1==0,"Too many PRBS for mu=0\n"); - break; - case 1: //30 kHz sc - AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); - if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s - else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s - break; - case 2: //60 kHz scs - AssertFatal(1==0,"scs_common should not be 60 kHz\n"); - break; - case 3: //120 kHz scs - AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); - break; - case 4: //240 kHz scs - AssertFatal(1==0,"scs_common should not be 60 kHz\n"); - if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s - else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s - else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); - break; - - if (N_RB == 100) - UE[CC_id]->N_TA_offset = 624; - else if (N_RB == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (N_RB == 25) - UE[CC_id]->N_TA_offset = 624/4; - } - if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75; - UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor); - LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB); + if (frame_parms[CC_id]->frame_type == TDD) + frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0]; } + #endif } - // printf("tx_max_power = %d -> amp %d\n",tx_max_power[0],get_tx_amp(tx_max_poHwer,tx_max_power)); init_openair0(); // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); @@ -764,15 +554,10 @@ int main( int argc, char **argv ) { if(IS_SOFTMODEM_DOFORMS) { load_softscope("nr",PHY_vars_UE_g[0][0]); } - number_of_cards = 1; - - for(int CC_id=0; CC_idrf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; - PHY_vars_UE_g[0][CC_id]->timing_advance = timing_advance; - } + init_NR_UE_threads(1); + config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); printf("UE threads created by %ld\n", gettid()); // wait for end of program diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 418ed54fc6..5902c8cca8 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -5,78 +5,76 @@ #include "PHY/defs_nr_UE.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" + + + +#define CONFIG_HLP_DLSCH_PARA "number of threads for dlsch processing 0 for no parallelization" /***************************************************************************************************************************************/ /* 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 */ +#define CALIBRX_OPT "calib-ue-rx" +#define CALIBRXMED_OPT "calib-ue-rx-med" +#define CALIBRXBYP_OPT "calib-ue-rx-byp" +#define DBGPRACH_OPT "debug-ue-prach" +#define NOL2CONNECT_OPT "no-L2-connect" +#define CALIBPRACH_OPT "calib-prach-tx" +#define DUMPFRAME_OPT "ue-dump-frame" + +/*------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters defining UE running mode */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CMDLINE_NRUEPARAMS_DESC { \ + {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ + {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ + {"dlsch-parallel", CONFIG_HLP_DLSCH_PARA, 0, iptr:(int32_t *)&nrUE_params.nr_dlsch_parallel, defintval:0, TYPE_UINT8, 0}, \ + {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ + {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ + {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \ +} + /*------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters defining UE running mode */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_UEMODEPARAMS_DESC { \ - {"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ - {"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ - {"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ - {"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ - {"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ - {"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ - {"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \ - {"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \ - } -#define CMDLINE_CALIBUERX_IDX 0 -#define CMDLINE_CALIBUERXMED_IDX 1 -#define CMDLINE_CALIBUERXBYP_IDX 2 -#define CMDLINE_DEBUGUEPRACH_IDX 3 -#define CMDLINE_NOL2CONNECT_IDX 4 -#define CMDLINE_CALIBPRACHTX_IDX 5 -#define CMDLINE_MEMLOOP_IDX 6 -#define CMDLINE_DUMPMEMORY_IDX 7 -/*------------------------------------------------------------------------------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters specific to UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_NRUEPARAMS_DESC { \ - {"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ - {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \ - {"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ - {"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \ - {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ - {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ - {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&UE_fo_compensation, defintval:0, TYPE_INT, 0}, \ - {"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} \ - } - -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters common to eNodeB and UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define CMDLINE_PARAMS_DESC_UE { \ - {"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}, \ - {"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}, \ - {"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}, \ - {"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} \ +#define CMDLINE_NRUE_PHYPARAMS_DESC { \ + { CALIBRX_OPT, CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ + { CALIBRXMED_OPT, CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ + { CALIBRXBYP_OPT, CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \ + { DBGPRACH_OPT, CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ + { NOL2CONNECT_OPT, CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ + {CALIBPRACH_OPT, CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \ + { DUMPFRAME_OPT, CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \ + {"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ + {"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \ + {"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ + {"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&(fp->nb_antennas_rx), defuintval:1, TYPE_UINT8, 0}, \ + {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&(fp->nb_antennas_tx), defuintval:1, TYPE_UINT8, 0}, \ + {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&(UE->UE_scan_carrier), defintval:0, TYPE_INT, 0}, \ + {"ue-fo-compensation", CONFIG_HLP_UEFO, PARAMFLAG_BOOL, iptr:&(UE->UE_fo_compensation), defintval:0, TYPE_INT, 0}, \ + {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ + {"r" , CONFIG_HLP_PRB, 0, iptr:&(fp->N_RB_DL), defintval:25, TYPE_UINT, 0}, \ + {"A" , CONFIG_HLP_TADV, 0, iptr:&(UE->timing_advance), defintval:0, TYPE_INT, 0}, \ + {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, u8ptr:&(fp->threequarter_fs), defintval:0, TYPE_UINT8, 0}, \ + {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ + {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&(UE->no_timing_correction), defintval:0, TYPE_INT, 0}, \ } -extern int T_port; -extern int T_nowait; -extern int T_dont_fork; +typedef struct { + uint64_t optmask; //mask to store boolean config options + uint8_t nr_dlsch_parallel; // number of threads for dlsch decoding, 0 means no parallelization + tpool_t Tpool; // thread pool +} nrUE_params_t; +extern uint64_t get_nrUE_optmask(void); +extern uint64_t set_nrUE_optmask(uint64_t bitmask); +extern nrUE_params_t *get_nrUE_params(void); +#ifdef NRUE_MAIN +nrUE_params_t nrUE_params; +#endif // In nr-ue.c extern int setup_nr_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); @@ -86,7 +84,6 @@ extern void init_NR_UE_threads(int); extern void reset_opp_meas(void); extern void print_opp_meas(void); void *UE_thread(void *arg); -void init_nr_ue_vars(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); -extern tpool_t *Tpool; -extern tpool_t *Tpool_dl; +void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag); + #endif diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c new file mode 100644 index 0000000000..4ddc7870d9 --- /dev/null +++ b/executables/ocp-gnb.c @@ -0,0 +1,1010 @@ +/* + * Author: Laurent Thomas, Open Cells Project + * all rights reserved + */ + +#define _GNU_SOURCE +#include +#include "assertions.h" +#include +#include + +#include "PHY/types.h" + +#include "PHY/INIT/phy_init.h" + +#include "PHY/defs_gNB.h" +#include "SCHED/sched_eNB.h" +#include "SCHED_NR/sched_nr.h" +#include "SCHED_NR/fapi_nr_l1.h" +#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "../../ARCH/COMMON/common_lib.h" + +#include "PHY/phy_extern.h" +#include "LAYER2/MAC/mac.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" +#include "LAYER2/MAC/mac_proto.h" +#include "RRC/LTE/rrc_extern.h" +#include "PHY_INTERFACE/phy_interface.h" +#include "common/utils/LOG/log_extern.h" +#include "UTIL/OTG/otg_tx.h" +#include "UTIL/OTG/otg_externs.h" +#include "UTIL/MATH/oml.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "enb_config.h" +#include "s1ap_eNB.h" +#include "SIMULATION/ETH_TRANSPORT/proto.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// should be in a shared lib +#include +#include +#include +#include + +// Global vars +#include +#include +#include +#include +volatile int oai_exit; +int single_thread_flag=1; +uint32_t do_forms=0; +unsigned int mmapped_dma=0; +int8_t threequarter_fs=0; + +uint32_t target_dl_mcs = 28; //maximum allowed mcs +uint32_t target_ul_mcs = 20; +int chain_offset=0; +uint16_t sl_ahead=6; +uint16_t sf_ahead=6; +uint32_t timing_advance = 0; +int transmission_mode=1; +int emulate_rf = 0; +int numerology = 0; +int usrp_tx_thread = 0; + + +int config_sync_var=-1; +pthread_mutex_t nfapi_sync_mutex; +pthread_cond_t nfapi_sync_cond; +int nfapi_sync_var=-1; +uint8_t nfapi_mode = NFAPI_MONOLITHIC; // Default to monolithic mode +double cpuf; + + +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. + + +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +time_stats_t softmodem_stats_mt; // main thread +time_stats_t softmodem_stats_hw; // hw acquisition +time_stats_t softmodem_stats_rxtx_sf; // total tx time +time_stats_t nfapi_meas; // total tx time +time_stats_t softmodem_stats_rx_sf; // total rx time +// not used but needed for link +openair0_config_t openair0_cfg[MAX_CARDS]; + +AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; +AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; +int flexran_agent_start(mid_t mod_id) { + memset (agent_rrc_xface, 0, sizeof(agent_rrc_xface)); + memset (agent_mac_xface, 0, sizeof(agent_mac_xface)); + return 0; +} +void flexran_agent_slice_update(mid_t module_idP) { +} +int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p) { + return 0; +} +void proto_agent_stop(mod_id_t mod_id) { +} +int split73=0; +void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { + AssertFatal(false, "Must not be called in this context\n"); +} +int stop_L1L2(module_id_t gnb_id) { + AssertFatal(false, "Must not be called in this context\n"); +} +int restart_L1L2(module_id_t gnb_id) { + AssertFatal(false, "Must not be called in this context\n"); +} + +static int wait_for_sync = 0; +static char *itti_dump_file = NULL; +static double snr_dB=20; +static int DEFBANDS[] = {7}; +static int DEFENBS[] = {0}; +static int DEFBFW[] = {0x00007fff}; + +extern double cpuf; + +short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655}; + +static inline int ocp_rxtx(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) { + nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; + start_meas(&softmodem_stats_rxtx_sf); + + // ******************************************************************* + + if (nfapi_mode == NFAPI_MODE_PNF) { + // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick + //add_subframe(&frame, &subframe, 4); + //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); + //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); + start_meas(&nfapi_meas); + oai_subframe_ind(proc->frame_rx, proc->slot_rx); + stop_meas(&nfapi_meas); + /*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| + gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || + gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || + gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || + gNB->UL_INFO.cqi_ind.number_of_cqis + ) { + LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n", + NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, + NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, + NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, + NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, + gNB->UL_INFO.cqi_ind.number_of_cqis, + frame_rx, slot_rx, + frame_tx, slot_tx); + }*/ + } + + /// NR disabling + // **************************************** + // Common RX procedures subframe n + pthread_mutex_lock(&gNB->UL_INFO_mutex); + gNB->UL_INFO.frame = proc->frame_rx; + gNB->UL_INFO.slot = proc->slot_rx; + gNB->UL_INFO.module_id = gNB->Mod_id; + gNB->UL_INFO.CC_id = gNB->CC_id; + gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); + pthread_mutex_unlock(&gNB->UL_INFO_mutex); + // RX processing + int tx_slot_type = nr_slot_select(cfg,proc->frame_tx,proc->slot_tx); + int rx_slot_type = nr_slot_select(cfg,proc->frame_rx,proc->slot_rx); + + if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { + // Do PRACH RU processing + L1_nr_prach_procedures(gNB,proc->frame_rx,proc->slot_rx); + phy_procedures_gNB_uespec_RX(gNB, proc->frame_rx, proc->slot_rx); + } + + if (oai_exit) return(-1); + + // ***************************************** + // TX processing for subframe n+sf_ahead + // run PHY TX procedures the one after the other for all CCs to avoid race conditions + // (may be relaxed in the future for performance reasons) + // ***************************************** + + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { + phy_procedures_gNB_TX(gNB, proc->frame_tx,proc->slot_tx, 1); + } + + stop_meas( &softmodem_stats_rxtx_sf ); + LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx); + return(0); +} + + +static void *process_stats_thread(void *param) { + PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; + reset_meas(&gNB->dlsch_encoding_stats); + reset_meas(&gNB->dlsch_scrambling_stats); + reset_meas(&gNB->dlsch_modulation_stats); + + while(!oai_exit) { + sleep(1); + print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL); + print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL); + print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL); + } + + return(NULL); +} + +void init_gNB_proc(int inst) { + PHY_VARS_gNB *gNB = RC.gNB[inst]; + gNB_L1_proc_t *proc = &gNB->proc; + gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; + gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; + L1_proc->instance_cnt = -1; + L1_proc_tx->instance_cnt = -1; + L1_proc->instance_cnt_RUs = 0; + L1_proc_tx->instance_cnt_RUs = 0; + proc->instance_cnt_prach = -1; + proc->instance_cnt_asynch_rxtx = -1; + proc->CC_id = 0; + proc->first_rx =1; + proc->first_tx =1; + proc->RU_mask =0; + proc->RU_mask_tx = (1<num_RU)-1; + proc->RU_mask_prach =0; + pthread_mutex_init( &gNB->UL_INFO_mutex, NULL); + gNB->threadPool = (tpool_t *)malloc(sizeof(tpool_t)); + gNB->respDecode = (notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t)); + char ul_pool[] = "-1,-1"; + initTpool(ul_pool, gNB->threadPool, false); + initNotifiedFIFO(gNB->respDecode); +} + +/// eNB kept in function name for nffapi calls, TO FIX +void init_gNB_phase2(RU_t *ru) { + int inst; + LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst); + + for (inst=0; instnum_RU:%d\n", gNB->num_RU); + phy_init_nr_gNB(gNB,0,0); + RC.gNB[inst]->num_RU=1; + RC.gNB[inst]->RU_list[0]=ru; + //init_precoding_weights(RC.gNB[inst][CC_id]); + } +} + +void init_gNB(int single_thread_flag,int wait_for_sync) { + for (int inst=0; instRCconfig_NR_L1\n"); + PHY_VARS_gNB *gNB= RC.gNB[inst]; + gNB->abstraction_flag = false; + gNB->single_thread_flag = true; + /*nr_polar_init(&gNB->nrPolar_params, + NR_POLAR_PBCH_MESSAGE_TYPE, + NR_POLAR_PBCH_PAYLOAD_BITS, + NR_POLAR_PBCH_AGGREGATION_LEVEL);*/ + LOG_I(PHY,"Registering with MAC interface module\n"); + AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface"); + 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->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t)); + //memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); + LOG_I(PHY,"Setting indication lists\n"); + gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list; + gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list; + /*gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list; + gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; + gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; + gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/ + gNB->prach_energy_counter = 0; + } + + LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n"); +} + + +void stop_gNB(int nb_inst) { +} + +static void get_options(void) { + paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { + memset((void *)&RC,0,sizeof(RC)); + /* Read RC configuration file */ + NRRCConfig(); + printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhd\n", RC.nb_nr_inst,RC.nb_nr_L1_inst,RC.nb_RU); + } + + AssertFatal(RC.nb_nr_L1_inst == 1 && RC.nb_RU == 1, "Only one gNB, one RU and one carrier is supported\n"); +} + +void set_default_frame_parms(nfapi_nr_config_request_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; + } +} + +static 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); + 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); +} + +void init_main_gNB(void) { + RCconfig_NR_L1(); + RCconfig_nr_macrlc(); + + if (RC.nb_nr_L1_inst>0) + AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n"); + + LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst); + RC.nrrrc = (gNB_RRC_INST **)calloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *),1); + LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc); + int gnb_id=0; // only 1 gnb per process, index 0 for now + RC.nrrrc[gnb_id] = (gNB_RRC_INST *)calloc(sizeof(gNB_RRC_INST),1); + MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ); + RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]); + openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(ITTI_MSG_DESTINATION_INSTANCE(msg_p)), &NRRRC_CONFIGURATION_REQ(msg_p)); + //AssertFatal(itti_create_task(TASK_GNB_APP, gNB_app_task, NULL) >= 0, ""); + AssertFatal(itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL) >= 0, ""); + //AssertFatal(itti_create_task(TASK_X2AP, x2ap_task, NULL) >= 0, ""); +} + +static void wait_nfapi_init(char *thread_name) { + printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); + pthread_mutex_lock( &nfapi_sync_mutex ); + + while (nfapi_sync_var<0) + pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); + + pthread_mutex_unlock(&nfapi_sync_mutex); + printf( "NFAPI: got sync (%s)\n", thread_name); +} + +void exit_function(const char *file, const char *function, const int line, const char *s) { + if (s != NULL) { + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); + } + + oai_exit = 1; + sleep(1); //allow lte-softmodem threads to exit first + exit(1); +} + +void stop_RU(int nb_ru) { + return; +} + +void OCPconfig_RU(RU_t *ru) { + int i = 0, j = 0; // Ru and gNB cardinality + paramdef_t RUParams[] = RUPARAMS_DESC; + paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; + config_getlist( &RUParamList, RUParams, sizeof(RUParams)/sizeof(paramdef_t), NULL); + AssertFatal( RUParamList.numelt == 1 && RC.nb_nr_L1_inst ==1,"" ); + ru->idx=0; + ru->nr_frame_parms = (NR_DL_FRAME_PARMS *)calloc(sizeof(NR_DL_FRAME_PARMS),1); + ru->frame_parms = (LTE_DL_FRAME_PARMS *)calloc(sizeof(LTE_DL_FRAME_PARMS),1); + ru->if_timing = synch_to_ext_device; + ru->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; + ru->gNB_list[i] = &RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; + + if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { + ru->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); + } + + if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) { + if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) { + ru->openair0_cfg.clock_source = internal; + LOG_D(PHY, "RU clock source set as internal\n"); + } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) { + ru->openair0_cfg.clock_source = external; + LOG_D(PHY, "RU clock source set as external\n"); + } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) { + ru->openair0_cfg.clock_source = gpsdo; + LOG_D(PHY, "RU clock source set as gpsdo\n"); + } else { + LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); + } + } else { + ru->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)) ) { + ru->if_south = REMOTE_IF5; //TBD: max value to avoid to call "ru" functions + ru->function = gNodeB_3GPP; + printf("Setting function for RU %d to gNodeB_3GPP\n",j); + } else { + } + + ru->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; + ru->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); + ru->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; + + for (i=0; inum_bands; i++) ru->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; + } //strcmp(local_rf, "yes") == 0 + else { + } + + ru->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); + ru->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); + ru->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); + ru->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + + if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { + ru->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; + + for (i=0; inum_gNB; i++) { + ru->bw_list[i] = (int32_t *)malloc16_clear((ru->nb_bfw)*sizeof(int32_t)); + + for (int b=0; bnb_bfw; b++) ru->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; + } + } + + return; +} + +// this is for RU with local RF unit +void fill_rf_config(RU_t *ru, char *rf_config_file) { + int i; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index + openair0_config_t *cfg = &ru->openair0_cfg; + int mu = gNB_config->ssb_config.scs_common.value; + int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; + fp->threequarter_fs=threequarter_fs; + + if (mu == NR_MU_0) { //or if LTE + if(N_RB == 100) { + if (fp->threequarter_fs) { + cfg->sample_rate=23.04e6; + cfg->samples_per_frame = 230400; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } else { + cfg->sample_rate=30.72e6; + cfg->samples_per_frame = 307200; + cfg->tx_bw = 10e6; + cfg->rx_bw = 10e6; + } + } else if(N_RB == 50) { + cfg->sample_rate=15.36e6; + cfg->samples_per_frame = 153600; + cfg->tx_bw = 5e6; + cfg->rx_bw = 5e6; + } else if (N_RB == 25) { + cfg->sample_rate=7.68e6; + cfg->samples_per_frame = 76800; + cfg->tx_bw = 2.5e6; + cfg->rx_bw = 2.5e6; + } else if (N_RB == 6) { + cfg->sample_rate=1.92e6; + cfg->samples_per_frame = 19200; + cfg->tx_bw = 1.5e6; + cfg->rx_bw = 1.5e6; + } else AssertFatal(1==0,"Unknown N_RB %d\n",N_RB); + } else if (mu == NR_MU_1) { + if(N_RB == 273) { + if (fp->threequarter_fs) { + AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } + } else if(N_RB == 217) { + if (fp->threequarter_fs) { + cfg->sample_rate=92.16e6; + cfg->samples_per_frame = 921600; + cfg->tx_bw = 80e6; + cfg->rx_bw = 80e6; + } else { + cfg->sample_rate=122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 80e6; + cfg->rx_bw = 80e6; + } + } else if(N_RB == 106) { + if (fp->threequarter_fs) { + cfg->sample_rate=46.08e6; + cfg->samples_per_frame = 460800; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + } else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 40e6; + cfg->rx_bw = 40e6; + } + } else { + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); + } + } else if (mu == NR_MU_3) { + if (N_RB == 66) { + cfg->sample_rate = 122.88e6; + cfg->samples_per_frame = 1228800; + cfg->tx_bw = 100e6; + cfg->rx_bw = 100e6; + } else if(N_RB == 32) { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } + } else { + AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); + } + + if (gNB_config->cell_config.frame_duplex_type.value==TDD) + cfg->duplex_mode = duplex_mode_TDD; + else //FDD + cfg->duplex_mode = duplex_mode_FDD; + + cfg->Mod_id = 0; + cfg->num_rb_dl=N_RB; + cfg->tx_num_channels=ru->nb_tx; + cfg->rx_num_channels=ru->nb_rx; + + for (i=0; inb_tx; i++) { + if (ru->if_frequency == 0) { + cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; + cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; + } else { + cfg->tx_freq[i] = (double)ru->if_frequency; + cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); + } + + cfg->tx_gain[i] = ru->att_tx; + cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; + cfg->configFilename = rf_config_file; + printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", + i, cfg->tx_gain[i], + cfg->rx_gain[i], + cfg->tx_freq[i], + cfg->rx_freq[i]); + } +} + +/* this function maps the RU tx and rx buffers to the available rf chains. + Each rf chain is is addressed by the card number and the chain on the card. The + rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple + antennas are mapped to successive RF chains on the same card. */ +int setup_RU_buffers(RU_t *ru) { + int i,j; + int card,ant; + //uint16_t N_TA_offset = 0; + NR_DL_FRAME_PARMS *frame_parms; + nfapi_nr_config_request_scf_t *config = &ru->config; + + if (ru) { + frame_parms = ru->nr_frame_parms; + printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); + } else { + printf("ru pointer is NULL\n"); + return(-1); + } + + int mu = config->ssb_config.scs_common.value; + int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; + + if (config->cell_config.frame_duplex_type.value == TDD) { + int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 + double factor=1; + + switch (mu) { + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n"); + + if (N_RB <= 25) factor = .25; // 7.68 Ms/s + else if (N_RB <=50) factor = .5; // 15.36 Ms/s + else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s + else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s + else AssertFatal(1==0,"Too many PRBS for mu=0\n"); + + break; + + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n"); + + if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s + else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + + break; + + case 2: //60 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + break; + + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n"); + break; + + case 4: //240 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + + if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s + else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s + else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); + + break; + + if (N_RB == 100) ru->N_TA_offset = 624; + else if (N_RB == 50) ru->N_TA_offset = 624/2; + else if (N_RB == 25) ru->N_TA_offset = 624/4; + } + + if (frame_parms->threequarter_fs == 1) factor = factor*.75; + + ru->N_TA_offset = (int)(N_TA_offset * factor); + LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor, + config->carrier_config.uplink_frequency.value, N_RB); + } else ru->N_TA_offset = 0; + + if (ru->openair0_cfg.mmapped_dma == 1) { + // replace RX signal buffers with mmaped HW versions + for (i=0; inb_rx; i++) { + card = i/4; + ant = i%4; + printf("Mapping RU id %u, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + free(ru->common.rxdata[i]); + ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; + printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); + + for (j=0; j<16; j++) { + printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); + ru->common.rxdata[i][j] = 16-j; + } + } + + for (i=0; inb_tx; i++) { + card = i/4; + ant = i%4; + printf("Mapping RU id %u, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + free(ru->common.txdata[i]); + ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; + printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); + + for (j=0; j<16; j++) { + printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); + ru->common.txdata[i][j] = 16-j; + } + } + } else { // not memory-mapped DMA + //nothing to do, everything already allocated in lte_init + } + + return(0); +} +int rx_rf(int rxBufOffet, int nbSamples, int nb_rx, int32_t **rxdata, openair0_device *rfdevice, openair0_timestamp *HWtimeStamp) { + void *rxp[nb_rx]; + + for (int i=0; itrx_read_func(rfdevice, + HWtimeStamp, + rxp, + nbSamples, + nb_rx); + + if (rxs != nbSamples ) + LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",nbSamples,rxs); + + return rxs; +} + +void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { + RU_proc_t *proc = &ru->proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + int i,txsymb; + int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); + int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); + int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame); + int sf_extension = 0; //sf_extension = ru->sf_extension; + int siglen=fp->get_samples_per_slot(slot,fp); + int flags=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(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); + + if(slot%(fp->slots_per_subframe/2)) + siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); + else + 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 + } + + if (cfg->cell_config.frame_duplex_type.value == TDD && + slot_type == NR_DOWNLINK_SLOT && + nextslot_type == NR_UPLINK_SLOT) { + flags = 3; // end of burst + } + + if (fp->freq_range==nr_FR2) { + // the beam index is written in bits 8-10 of the flags + // bit 11 enables the gpio programming + int beam=0; + + if (slot==0) beam = 11; //3 for boresight & 8 to enable + + /* + if (slot==0 || slot==40) beam=0&8; + if (slot==10 || slot==50) beam=1&8; + if (slot==20 || slot==60) beam=2&8; + if (slot==30 || slot==70) beam=3&8; + */ + flags |= beam<<8; + } + + void *txp[ru->nb_tx]; + + for (i=0; inb_tx; i++) + txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension]; + + // prepare tx buffer pointers + unsigned int 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); + AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); + } +} + +static void *ru_thread( void *param ) { + RU_t *ru = (RU_t *)param; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); + nr_dump_frame_parms(fp); + AssertFatal(openair0_device_load(&ru->rfdevice,&ru->openair0_cfg)==0,"Cannot connect to local radio\n"); + AssertFatal(ru->rfdevice.trx_start_func(&ru->rfdevice) == 0,"Could not start the RF device\n"); + int64_t slot=-1; + int64_t nextHWTSshouldBe=0, nextRxTSlogical=0; + // weird globals, used in NR_IF_Module.c + sf_ahead = (uint16_t) ceil((float)6/(0x01<numerology_index)); + sl_ahead = sf_ahead*fp->slots_per_subframe; + + // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices + + while (!oai_exit) { + int nextSlot=(slot+1)%fp->slots_per_frame; + uint32_t samples_per_slot = fp->get_samples_per_slot(nextSlot,fp); + int rxBuffOffset=fp->get_samples_slot_timestamp(nextSlot,fp,0); + AssertFatal(rxBuffOffset + samples_per_slot <= fp->samples_per_frame, "Will read outside allocated buffer\n"); + int samples=fp->get_samples_per_slot(nextSlot,fp); + openair0_timestamp HWtimeStamp=0; //for multi RU + int rxs=rx_rf(rxBuffOffset, + samples, + ru->nb_rx, + ru->common.rxdata, + &ru->rfdevice, + &HWtimeStamp); + LOG_D(PHY,"Reading %d samples for slot %d\n",samples_per_slot,nextSlot); + + if ( HWtimeStamp != nextHWTSshouldBe) + LOG_E(HW,"reading a stream must be continuous, %ld, %ld\n", HWtimeStamp, nextHWTSshouldBe); + + nextHWTSshouldBe=HWtimeStamp+rxs; + ru->proc.timestamp_rx=nextRxTSlogical; + nextRxTSlogical+=samples_per_slot; + int64_t HW_to_logical_RxTSoffset=(int64_t)HWtimeStamp-(int64_t)ru->proc.timestamp_rx; + ru->proc.frame_rx = (ru->proc.timestamp_rx / (fp->samples_per_subframe*10))&1023; + uint32_t idx_sf = ru->proc.timestamp_rx / fp->samples_per_subframe; + float offsetInSubframe=ru->proc.timestamp_rx % fp->samples_per_subframe; + ru->proc.tti_rx = (idx_sf * fp->slots_per_subframe + + lroundf(offsetInSubframe / fp->samples_per_slot0))% + fp->slots_per_frame; + LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", + ru->idx, 0, + (unsigned long long int)ru->proc.timestamp_rx, + (int)ru->ts_offset,ru->proc.frame_rx,ru->proc.tti_rx,ru->proc.tti_tx,fp->slots_per_frame); + int slot_type = nr_slot_select(&ru->gNB_list[0]->gNB_config,ru->proc.frame_rx,ru->proc.tti_rx); + + if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { + nr_fep_full(ru,ru->proc.tti_rx); + + for (int 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)); + + LOG_D(PHY, "rxdataF energy: %d\n", signal_energy(ru->common.rxdataF[0], fp->symbols_per_slot*fp->ofdm_symbol_size)); + } + + gNB_L1_proc_t *gNBproc=&RC.gNB[0][0].proc; + gNB_L1_rxtx_proc_t *L1_proc = &gNBproc->L1_proc; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + gNBproc->timestamp_rx = ru->proc.timestamp_rx; + L1_proc->frame_rx = gNBproc->frame_rx = gNBproc->frame_prach = ru->proc.frame_rx = + (ru->proc.timestamp_rx / (fp->samples_per_subframe*10))&1023; + L1_proc->slot_rx = gNBproc->slot_rx = gNBproc->slot_prach = + ru->proc.tti_rx; // computed before in caller function + L1_proc->timestamp_tx = gNBproc->timestamp_tx = ru->proc.timestamp_tx = + ru->proc.timestamp_rx + + sf_ahead*fp->samples_per_subframe; + L1_proc->frame_tx = gNBproc->frame_tx = ru->proc.frame_tx = + (gNBproc->timestamp_tx / (fp->samples_per_subframe*10))&1023; + L1_proc->slot_tx = ru->proc.tti_tx = + (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; + + if (ocp_rxtx(&RC.gNB[0][0],L1_proc) < 0) + LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",RC.gNB[0][0].Mod_id,RC.gNB[0][0].CC_id); + + // do TX front-end processing if needed (precoding and/or IDFTs) + //ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); + nr_feptx_prec(ru,ru->proc.frame_tx,ru->proc.tti_tx); + // do OFDM with/without TX front-end processing if needed + //ru->feptx_ofdm + nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + + if (nr_slot_select(cfg,ru->proc.frame_tx, ru->proc.tti_tx ) != NR_UPLINK_SLOT) { + int aa=0; // antenna 0 hardcoded + NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; + nr_feptx0(ru,ru->proc.tti_tx,0,fp->symbols_per_slot,aa); + int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(ru->proc.tti_tx,fp,0)]; + int slot_sizeF = (fp->ofdm_symbol_size)* + ((NFAPI_CP_NORMAL == 1) ? 12 : 14); + LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %ld) %d dB, txp (freq) %d dB\n", + ru->proc.frame_tx,ru->proc.tti_tx,ru->proc.timestamp_tx, + dB_fixed(signal_energy((int32_t *)txdata,fp->get_samples_per_slot(ru->proc.tti_tx,fp))), + dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); + } + + // do outgoing fronthaul (south) if needed + tx_rf(ru,ru->proc.frame_tx,ru->proc.tti_tx,ru->proc.timestamp_tx+HW_to_logical_RxTSoffset); + slot++; + } + + printf( "Exiting ru_thread \n"); + ru->rfdevice.trx_end_func(&ru->rfdevice); + static int ru_thread_status = 0; + return &ru_thread_status; +} + +void launch_NR_RU(RU_t *ru, char *rf_config_file) { + LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n", + RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs()); + LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); + + for (int ru_id=0; ru_idrf_config_file = rf_config_file; + ru->idx = ru_id; + ru->ts_offset = 0; + // use gNB_list[0] as a reference for RU frame parameters + // NOTE: multiple CC_id are not handled here yet! + LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p rf_config_file:%s\n", + __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], ru->rf_config_file); + LOG_E(PHY,"ru->gNB_list ru->num_gNB hardcoded: one RU connected to carrier 0 of gNB 0\n"); + ru->gNB_list[0] = &RC.gNB[0][0]; + ru->num_gNB=1; + LOG_I(PHY,"Copying frame parms from gNB in RC to ru %d and frame_parms in ru\n",ru->idx); + RU_proc_t *proc = &ru->proc; + threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "MainLoop", -1, OAI_PRIORITY_RT_MAX ); + } +} + +void init_eNB_afterRU(void) { + AssertFatal(false,""); +} + +int main( int argc, char **argv ) { + AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY), + "[SOFTMODEM] Error, configuration module init failed\n"); + logInit(); +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN" +#endif + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + configure_linux(); + get_options (); + get_common_options(SOFTMODEM_GNB_BIT ); + AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n"); + cpuf=get_cpu_freq_GHz(); + itti_init(TASK_MAX, tasks_info); + set_taus_seed (0); + init_opt(); + init_pdcp(); + init_main_gNB(); + init_gNB(true, wait_for_sync); + /* Start the agent. If it is turned off in the configuration, it won't start */ + RCconfig_nr_flexran(); + + for (int i = 0; i < RC.nb_nr_L1_inst; i++) { + flexran_agent_start(i); + } + + /* + *nfapi stuff very buggy in 4G, not yet implemented in 5G + */ + // init UE_PF_PO and mutex lock (paging from S1AP) + pthread_mutex_init(&ue_pf_po_mutex, NULL); + printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); + pthread_cond_init(&nfapi_sync_cond,NULL); + pthread_mutex_init(&nfapi_sync_mutex, NULL); + const char *nfapi_mode_str[] = { + "MONOLITHIC", "PNF", "VNF", + }; + AssertFatal(nfapi_mode < 3,""); + printf("NFAPI MODE:%s\n", nfapi_mode_str[nfapi_mode]); + + if (nfapi_mode==NFAPI_MODE_VNF) // VNF + wait_nfapi_init("main?"); + + for (int i=0; iconfigured, "Remain threads to manage\n"); + + printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); + config_sync_var=0; + + if (nfapi_mode==NFAPI_MODE_PNF) { // PNF + wait_nfapi_init("main?"); + } + + printf("wait RUs\n"); + printf("ALL RUs READY!\n"); + printf("RC.nb_RU:%d\n", RC.nb_RU); + // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) + printf("ALL RUs ready - init gNBs\n"); + LOG_E(PHY,"configuring RU from file, hardcoded one gNB for one RU, one carrier\n"); + RU_t ru= {0}; + OCPconfig_RU(&ru); + ru.nr_frame_parms->threequarter_fs=threequarter_fs; + fill_rf_config(&ru,ru.rf_config_file); + init_gNB_phase2(&ru); + memcpy((void *)ru.nr_frame_parms,&RC.gNB[0][0].frame_parms,sizeof(NR_DL_FRAME_PARMS)); + memcpy((void *)&ru.config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru.config)); + AssertFatal(setup_RU_buffers(&ru)==0,"Inconsistent configuration"); + nr_phy_init_RU(&ru); + init_gNB_proc(0); // only instance 0 (one gNB per process) + + if (RC.nb_RU >0) { + printf("Initializing RU threads\n"); + launch_NR_RU(&ru, get_softmodem_params()->rf_config_file); + } + + if (opp_enabled ==1) { + pthread_t t; + threadCreate(&t, process_stats_thread, + (void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW); + } + + if(IS_SOFTMODEM_DOFORMS) { + scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]}; + load_softscope("nr",&tmp); + } + + while(!oai_exit) + sleep(1); + + logClean(); + printf("Bye.\n"); + return 0; +} diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 449d2e0957..a6035122c0 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -56,6 +56,7 @@ extern "C" #define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" #define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n" +#define CONFIG_HLP_SA "run gNB in standalone mode\n" #define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n" #define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" #define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" @@ -63,13 +64,14 @@ extern "C" #define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" #define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n" #define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n" +#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n" #define CONFIG_HLP_CHOFF "Channel id offset\n" #define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n" #define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" #define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" #define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" - +#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n" //#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation" #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" @@ -99,6 +101,7 @@ extern "C" #define TP_CONFIG softmodem_params.threadPoolConfig #define PHY_TEST softmodem_params.phy_test #define DO_RA softmodem_params.do_ra +#define SA softmodem_params.sa #define WAIT_FOR_SYNC softmodem_params.wait_for_sync #define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag #define CHAIN_OFFSET softmodem_params.chain_offset @@ -108,6 +111,7 @@ extern "C" #define TIMING_SOURCE softmodem_params.timing_source #define SEND_DMRSSYNC softmodem_params.send_dmrs_sync #define USIM_TEST softmodem_params.usim_test +#define USE_256QAM_TABLE softmodem_params.use_256qam_table #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; @@ -117,12 +121,14 @@ extern "C" {"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \ {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \ + {"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, iptr:&SA, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \ {"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \ {"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ {"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \ {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \ + {"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ @@ -135,6 +141,7 @@ extern "C" {"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \ {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ + {"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \ } @@ -209,6 +216,7 @@ typedef struct { char threadPoolConfig[1024]; int phy_test; int do_ra; + int sa; uint8_t usim_test; int emulate_rf; int wait_for_sync; //eNodeB only @@ -220,6 +228,7 @@ typedef struct { uint32_t timing_source; int hw_timing_advance; uint32_t send_dmrs_sync; + int use_256qam_table; } softmodem_params_t; extern uint64_t get_softmodem_optmask(void); @@ -230,6 +239,7 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr); #define SOFTMODEM_RTSIGNAL (SIGRTMIN+1) extern void set_softmodem_sighandler(void); extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; #ifdef __cplusplus } #endif diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 59857659c1..3dfbc2811d 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -720,9 +720,6 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa } int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) { - if (RC.ru == 0) { - return -1; - } if (RC.eNB == 0) { return -2; @@ -847,9 +844,6 @@ int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n req->ul_config_request_body.srs_present ); - if (RC.ru == 0) { - return -1; - } if (RC.eNB == 0) { return -2; diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 7ab8be5746..f76cad87f7 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -333,11 +333,11 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { // wake up TX for subframe n+sf_ahead // lock the TX mutex and make sure the thread is ready - if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt ); - exit_fun( "error locking mutex_rxtx" ); - return(-1); - } + //if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { + // LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt ); + // exit_fun( "error locking mutex_rxtx" ); + // return(-1); + //} { static uint16_t old_sf = 0; @@ -348,10 +348,41 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { old_sf = sf; old_sfn = sfn; - if (old_sf == 0 && old_sfn % 100==0) LOG_W( PHY,"[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n", sfn, sf, old_sfn, old_sf, proc->frame_rx, proc->subframe_rx); + if (old_sf == 0 && old_sfn % 100==0) + LOG_D(PHY, + "[eNB] sfn/sf:%d%d old_sfn/sf:%d%d proc[rx:%d%d]\n", + sfn, + sf, + old_sfn, + old_sf, + proc->frame_rx, + proc->subframe_rx); + } + // wake up TX for subframe n+sf_ahead + // lock the TX mutex and make sure the thread is ready + if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB RXTX thread %d (IC %d)\n", L1_proc->subframe_rx&1,L1_proc->instance_cnt ); + //exit_fun( "error locking mutex_rxtx" ); + return(-1); + } + static int busy_log_cnt=0; + if(L1_proc->instance_cnt < 0){ + ++L1_proc->instance_cnt; + if(busy_log_cnt!=0){ + LOG_E(MAC,"RCC singal to rxtx frame %d subframe %d busy end %d (frame %d subframe %d)\n",L1_proc->frame_rx,L1_proc->subframe_rx,busy_log_cnt,proc->frame_rx,proc->subframe_rx); + } + busy_log_cnt=0; + }else{ + if(busy_log_cnt==0){ + LOG_E(MAC,"RCC singal to rxtx frame %d subframe %d busy %d (frame %d subframe %d)\n",L1_proc->frame_rx,L1_proc->subframe_rx,L1_proc->instance_cnt,proc->frame_rx,proc->subframe_rx); + } + pthread_mutex_unlock( &L1_proc->mutex ); + busy_log_cnt++; + return(0); } - ++L1_proc->instance_cnt; + pthread_mutex_unlock( &L1_proc->mutex ); + //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx); // We have just received and processed the common part of a subframe, say n. // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired @@ -374,9 +405,6 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { return(-1); } - //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__); - pthread_mutex_unlock( &L1_proc->mutex ); - //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__); return(0); } @@ -435,6 +463,7 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio } if(index == -1){ LOG_E(MAC,"phy_rach_indication : num of rach reach max \n"); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 0; } UL_RCC_INFO.rach_ind[index] = *ind; @@ -499,6 +528,7 @@ int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indicatio } if(index == -1){ LOG_E(MAC,"phy_harq_indication : num of harq reach max \n"); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 0; } UL_RCC_INFO.harq_ind[index] = *ind; @@ -538,6 +568,7 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_ } if(index == -1){ LOG_E(MAC,"phy_crc_indication : num of crc reach max \n"); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 0; } UL_RCC_INFO.crc_ind[index] = *ind; @@ -603,6 +634,7 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t } if(index == -1){ LOG_E(MAC,"phy_rx_indication : num of rx reach max \n"); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 0; } UL_RCC_INFO.rx_ind[index] = *ind; @@ -686,6 +718,7 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t } if(index == -1){ LOG_E(MAC,"phy_sr_indication : num of sr reach max \n"); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 0; } UL_RCC_INFO.sr_ind[index] = *ind; @@ -737,6 +770,7 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_ } if(index == -1){ LOG_E(MAC,"phy_cqi_indication : num of cqi reach max \n"); + pthread_mutex_unlock(&eNB->UL_INFO_mutex); return 0; } UL_RCC_INFO.cqi_ind[index] = *ind; 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 e1d06335f5..0a83c1a27f 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 @@ -44,7 +44,7 @@ #define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01 #define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02 #define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03 - +#define FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH 0x04 #define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01 #define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02 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 10058c441e..9df9be4cbd 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 @@ -23,6 +23,7 @@ #include "PHY/impl_defs_nr.h" #define NFAPI_UE_MAX_NUM_CB 8 +#define NFAPI_MAX_NUM_UL_PDU 8 /* typedef unsigned int uint32_t; @@ -155,7 +156,7 @@ typedef struct { uint16_t slot; fapi_nr_tx_config_t tx_config; uint16_t number_of_pdus; - fapi_nr_tx_request_body_t *tx_request_body; + fapi_nr_tx_request_body_t tx_request_body[NFAPI_MAX_NUM_UL_PDU]; } fapi_nr_tx_request_t; /// This struct replaces: @@ -170,6 +171,7 @@ typedef struct { uint8_t prach_format; /// Num RA uint8_t num_ra; + uint8_t prach_slot; uint8_t prach_start_symbol; /// 38.211 (NCS 38.211 6.3.3.1). uint16_t num_cs; @@ -179,6 +181,8 @@ typedef struct { uint8_t restricted_set; /// see TS 38.211 (6.3.3.2). uint16_t freq_msg1; + // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble + uint8_t ssb_nb_in_ro; // nfapi_nr_ul_beamforming_t beamforming; } fapi_nr_ul_config_prach_pdu; @@ -468,6 +472,21 @@ typedef struct { uint8_t cbgti; uint8_t codeBlockGroupFlushIndicator; // to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t + // 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; + /// MCS table for this DLSCH + uint8_t mcs_table; + + uint16_t pduBitmap; } fapi_nr_dl_config_dlsch_pdu_rel15_t; typedef struct { @@ -779,7 +798,7 @@ typedef struct { } fapi_nr_pusch_power_control_t; typedef enum {tx_config_codebook = 1, tx_config_nonCodebook = 2} tx_config_t; -typedef enum {transform_precoder_disabled = 0, transform_precoder_enabled = 1} transform_precoder_t; +typedef enum {transform_precoder_enabled = 0, transform_precoder_disabled = 1} transform_precoder_t; typedef enum { codebook_subset_fullyAndPartialAndNonCoherent = 1, codebook_subset_partialAndNonCoherent = 2, @@ -1000,6 +1019,7 @@ typedef struct typedef struct { uint8_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 + uint8_t tdd_period_in_slots; fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list; } fapi_nr_tdd_table_t; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 029ee20d8b..12748b7a9e 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -321,6 +321,7 @@ typedef enum { #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_CONFIG_INDEX_TAG 0x1029 #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 @@ -385,7 +386,6 @@ typedef struct 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 @@ -401,7 +401,9 @@ typedef struct 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_uint8_tlv_t prach_ConfigurationIndex;//PRACH configuration index. Value:0->255 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 @@ -628,30 +630,30 @@ typedef struct { typedef struct { // The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535. - uint16_t RNTI[MAX_DCI_CORESET]; + uint16_t RNTI; // 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]; + uint16_t ScramblingId; // 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]; + uint16_t ScramblingRNTI; // CCE start Index used to send the DCI Value: 0->135 - uint8_t CceIndex[MAX_DCI_CORESET]; + uint8_t CceIndex; // Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16 - uint8_t AggregationLevel[MAX_DCI_CORESET]; + uint8_t AggregationLevel; // Precoding and Beamforming structure See Table 3-43 - nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET]; + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming; // 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]; + uint8_t beta_PDCCH_1_0; // 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]; + uint8_t powerControlOffsetSS; // The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8 - uint16_t PayloadSizeBits[MAX_DCI_CORESET]; + uint16_t PayloadSizeBits; // 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]; + uint8_t Payload[DCI_PAYLOAD_BYTE_LEN]; } nfapi_nr_dl_dci_pdu_t; @@ -696,7 +698,7 @@ typedef struct { ///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot uint16_t numDlDci; ///DL DCI PDU - nfapi_nr_dl_dci_pdu_t dci_pdu; + nfapi_nr_dl_dci_pdu_t dci_pdu[MAX_DCI_CORESET]; } nfapi_nr_dl_tti_pdcch_pdu_rel15_t; typedef struct { @@ -1258,7 +1260,7 @@ typedef struct typedef struct { - uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 65535 + uint8_t pdu_idx;//This value is an index for number of PDU identified by nPDU in this message Value: 0 -> 255 } nfapi_nr_ul_tti_request_number_of_ue_t; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index 394bfc58ff..cff24500b6 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -955,7 +955,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", + NFAPI_TRACE(NFAPI_TRACE_INFO, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ts.tv_sec, ts.tv_nsec, ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4, tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->sf_offset, phy->sf_offset_filtered, @@ -1016,7 +1016,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) { phy->adjustment = NFAPI_SFNSF2DEC(new_sfn_sf) - NFAPI_SFNSF2DEC(curr_sfn_sf); - NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_sf_offset_filtered:%d phy->previous_sf_offset_filtered:%d phy->sf_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_sf_offset_filtered, phy->previous_sf_offset_filtered, phy->sf_offset_trend); + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF to VNF phy_id:%d adjustment%d phy->previous_sf_offset_filtered:%d phy->previous_sf_offset_filtered:%d phy->sf_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_sf_offset_filtered, phy->previous_sf_offset_filtered, phy->sf_offset_trend); phy->previous_t1 = 0; phy->previous_t2 = 0; diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index efa5abdc90..1afe82497a 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -347,13 +347,13 @@ void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f) } break; case 8: - e1=e+(E/6); - e2=e1+(E/6); - e3=e2+(E/6); - e4=e3+(E/6); - e5=e4+(E/6); - e6=e5+(E/6); - e7=e6+(E/6); + e1=e+(E/8); + e2=e1+(E/8); + e3=e2+(E/8); + e4=e3+(E/8); + e5=e4+(E/8); + e6=e5+(E/8); + e7=e6+(E/8); for (int j = 0,j2=0; j< E/8; j++,j2+=8){ e[j] = f[j2]; e1[j] = f[j2+1]; @@ -407,8 +407,16 @@ int nr_rate_matching_ldpc(uint8_t Ilbrm, #ifdef RM_DEBUG 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); + AssertFatal(Foffset <= E, + "Foffset %d > E %d " + "(Ilbrm %d, Tbslbrm %d, Z %d, BG %d, C %d)\n", + Foffset, E, + Ilbrm, Tbslbrm, Z, BG, C); + AssertFatal(Foffset <= Ncb, + "Foffset %d > Ncb %d " + "(Ilbrm %d, Tbslbrm %d, Z %d, BG %d, C %d)\n", + Foffset, Ncb, + Ilbrm, Tbslbrm, Z, BG, C); if (ind >= Foffset && ind < (F+Foffset)) ind = F+Foffset; diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index baea52083f..8ad928f8a0 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -121,13 +121,13 @@ int phy_init_RU(RU_t *ru) { /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ //AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), //"nb_antennas_rx too large"); - ru->prach_rxsigF = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *)); + ru->prach_rxsigF[0] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *)); for (j=0; j<4; j++) ru->prach_rxsigF_br[j] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *)); for (i=0; inb_rx; i++) { - ru->prach_rxsigF[i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); - LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]); + ru->prach_rxsigF[0][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); + LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[0][i]); for (j=0; j<4; j++) { ru->prach_rxsigF_br[j][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); @@ -230,14 +230,14 @@ void phy_free_RU(RU_t *ru) { } for (i = 0; i < ru->nb_rx; i++) { - free_and_zero(ru->prach_rxsigF[i]); + free_and_zero(ru->prach_rxsigF[0][i]); for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]); } for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]); - free_and_zero(ru->prach_rxsigF); + free_and_zero(ru->prach_rxsigF[0]); /* ru->prach_rxsigF_br is not allocated -> don't free */ for (i = 0; i < RC.nb_L1_inst; i++) { diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 1859bfb90a..5f38c63bd1 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -43,10 +43,10 @@ #include "SCHED_NR/fapi_nr_l1.h" #include "nfapi_nr_interface.h" +#include "PHY/NR_REFSIG/ul_ref_seq_nr.h" + /* extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn); - -extern int32_t get_nr_uldl_offset(int nr_bandP); extern openair0_config_t openair0_cfg[MAX_CARDS]; */ @@ -84,8 +84,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, 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; - /*LTE_eNB_SRS *const srs_vars = gNB->srs_vars; - LTE_eNB_PRACH *const prach_vars = &gNB->prach_vars;*/ int i; int Ptx=cfg->carrier_config.num_tx_ant.value; @@ -98,19 +96,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, while(gNB->configured == 0) usleep(10000); load_dftslib(); - /* - LOG_I(PHY,"[gNB %"PRIu8"] Initializing DL_FRAME_PARMS : N_RB_DL %"PRIu8", PHICH Resource %d, PHICH Duration %d nb_antennas_tx:%u nb_antennas_rx:%u PRACH[rootSequenceIndex:%u prach_Config_enabled:%u configIndex:%u highSpeed:%u zeroCorrelationZoneConfig:%u freqOffset:%u]\n", - gNB->Mod_id, - fp->N_RB_DL,fp->phich_config_common.phich_resource, - fp->phich_config_common.phich_duration, - fp->nb_antennas_tx, fp->nb_antennas_rx, - fp->prach_config_common.rootSequenceIndex, - fp->prach_config_common.prach_Config_enabled, - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset - );*/ + LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_gNB][MOD %02"PRIu8"][]\n", gNB->Mod_id); crcTableInit(); init_scrambling_luts(); @@ -136,6 +122,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, nr_generate_modulation_table(); 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 ***)); uint32_t ****pdsch_dmrs = gNB->nr_gold_pdsch_dmrs; @@ -196,12 +183,14 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } - nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value); // TODO scramblingID currently hardcoded to 0, to be taken from higher layer parameter scramblingID when implemented + nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value); + + /* Generate low PAPR type 1 sequences for PUSCH DMRS, these are used if transform precoding is enabled. */ + generate_lowpapr_typ1_refsig_sequences(SHRT_MAX); /// Transport init necessary for NR synchro init_nr_transport(gNB); - gNB->first_run_I0_measurements = 1; common_vars->rxdata = (int32_t **)malloc16(Prx*sizeof(int32_t*)); @@ -259,9 +248,7 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; - printf("Before ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]); 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 *) ); @@ -278,7 +265,6 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, 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*) ); - 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 ); @@ -295,16 +281,13 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, 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) ); } - 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]); pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot); } //ulsch_id /* for (ulsch_id=0; ulsch_idUE_stats_ptr[ulsch_id] = &gNB->UE_stats[ulsch_id]; */ - printf("After ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]); return (0); } @@ -390,6 +373,11 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) /* for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) gNB->UE_stats_ptr[UE_id] = NULL; */ + + + free_gnb_lowpapr_sequences(); + + } /* void install_schedule_handlers(IF_Module_t *if_inst) @@ -433,11 +421,18 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, //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->nr_band = 78; -// fp->threequarter_fs= 0; - + if (mu==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->nr_band = 78; + // fp->threequarter_fs= 0; + } else if (mu==3) { + fp->dl_CarrierFreq = 27524520000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); + fp->ul_CarrierFreq = 27524520000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); + fp->nr_band = 261; + // fp->threequarter_fs= 0; + } + gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band); nr_init_frame_parms(gNB_config, fp); @@ -451,52 +446,26 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion; NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; + int32_t dlul_offset = 0; - /* - 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; - } - - - 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; uint64_t dl_bw_khz = (12*gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value); fp->dl_CarrierFreq = ((dl_bw_khz>>1) + gNB_config->carrier_config.dl_frequency.value)*1000 ; - - int32_t dlul_offset = 0; - lte_frame_type_t frame_type = 0; - get_band(fp->dl_CarrierFreq,&fp->nr_band,&dlul_offset,&frame_type); - uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value); fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ; - AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+dlul_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band); + fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + + get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset); + dlul_offset *= 1000; + + AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + dlul_offset); + LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset); + 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, @@ -515,11 +484,12 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { fd_occasion = 0; nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config; short_sequence = prach_config->prach_sequence_length.value; +// for(fd_occasion = 0; fd_occasion <= prach_config->num_prach_fd_occasions.value ; fd_occasion) { // TODO Need to handle for msg1-fdm > 1 num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value; rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value; compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u); - +// } RC.gNB[Mod_id]->configured = 1; init_symbol_rotation(fp,fp->dl_CarrierFreq); diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 28b13112ce..648b820f07 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -107,12 +107,14 @@ int nr_phy_init_RU(RU_t *ru) { /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ // AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), // "nb_antennas_rx too large"); - ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); - - for (i=0; inb_rx; i++) { - // largest size for PRACH FFT is 4x98304 (16*24576) - ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) ); - LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]); + for (j=0;jprach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); + + for (i=0; inb_rx; i++) { + // largest size for PRACH FFT is 4x98304 (16*24576) + ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) ); + LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]); + } } AssertFatal(RC.nb_nr_L1_inst <= NUMBER_OF_eNB_MAX,"gNB instances %d > %d\n", @@ -186,10 +188,12 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]); free_and_zero(ru->common.rxdataF); - for (i = 0; i < ru->nb_rx; i++) { - free_and_zero(ru->prach_rxsigF[i]); + for (j=0;jnb_rx; i++) { + free_and_zero(ru->prach_rxsigF[j][i]); + } } - + for (i = 0; i < RC.nb_nr_L1_inst; i++) { for (p = 0; p < 15; p++) { for (j=0; jnb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 39e99e6ec3..8bcc58160f 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -41,543 +41,22 @@ #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/nr_refsig.h" -//uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10}; - -/*void phy_config_sib1_ue(uint8_t Mod_id,int CC_id, - uint8_t eNB_id, - TDD_Config_t *tdd_Config, - uint8_t SIwindowsize, - uint16_t SIperiod) -{ - - NR_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - - if (tdd_Config) { - fp->tdd_config = tdd_Config->subframeAssignment; - fp->tdd_config_S = tdd_Config->specialSubframePatterns; - } - - fp->SIwindowsize = SIwindowsize; - fp->SIPeriod = SIperiod; -} - -void phy_config_sib2_ue(uint8_t Mod_id,int CC_id, - uint8_t eNB_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CarrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) -{ - - PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; - NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - int i; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_IN); - - LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id); - - ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - - ue->prach_vars[eNB_id]->prach_Config_enabled=1; - //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; - ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag; - ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; - //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset; - - //compute_prach_seq(fp->prach_config_common.rootSequenceIndex, - // fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - // fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - // fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, - // fp->frame_type,ue->X_u); - - - - fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon.deltaPUCCH_Shift; - fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon.nRB_CQI; - fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon.nCS_AN; - fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN; - - - - fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon.referenceSignalPower; - fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon.p_b; - - - fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; - fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; - fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; - fp->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = dmrs1_tab_ue[radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift]; - - - init_ul_hopping(fp); - fp->soundingrs_ul_config_common.enabled_flag = 0; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; - } - - - - fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUSCH; - fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon.alpha; - fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH; - fp->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaPreambleMsg3; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b; - - fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx; - - // Now configure some of the Physical Channels - - // PUCCH - init_ncs_cell(fp,ue->ncs_cell); - - init_ul_hopping(fp); - - // PCH - init_ue_paging_info(ue,radioResourceConfigCommon->pcch_Config.defaultPagingCycle,radioResourceConfigCommon->pcch_Config.nB); - - // MBSFN - - if (mbsfn_SubframeConfigList != NULL) { - fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count; - - for (i=0; ilist.count; i++) { - fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; - fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; - - if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { - fp->MBSFN_config[i].fourFrames_flag = 0; - fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration - fp->MBSFN_config[i].fourFrames_flag = 1; - fp->MBSFN_config[i].mbsfn_SubframeConfig = - mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| - (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]<<16); - - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, - fp->MBSFN_config[i].mbsfn_SubframeConfig); - } - } - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_OUT); - -} - -void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx, - long mbsfn_AreaId_r9) -{ - - NR_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - - - LOG_I(PHY,"[UE%d] Applying MBSFN_Area_id %ld for index %d\n",Mod_id,mbsfn_AreaId_r9,mbsfn_Area_idx); - - if (mbsfn_Area_idx == 0) { - fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9; - LOG_N(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n"); - } - - lte_gold_mbsfn(fp,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_mbsfn_table,fp->Nid_cell_mbsfn); - -}*/ - - -/* - * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover - */ -/*void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) -{ - - if(mobilityControlInfo!=NULL) { - RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; - LOG_I(PHY,"radioResourceConfigCommon %p\n", radioResourceConfigCommon); - memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, - (void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms, - sizeof(NR_DL_FRAME_PARMS)); - PHY_vars_UE_g[Mod_id][CC_id]->ho_triggered = 1; - //PHY_vars_UE_g[UE_id]->UE_mode[0] = PRACH; - - NR_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms; - // int N_ZC; - // uint8_t prach_fmt; - // int u; - - LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n", - Mod_id,eNB_id); - - ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - ue->prach_vars[eNB_id]->prach_Config_enabled=1; - //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; - ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; - ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; - //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; - - // prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type); - // N_ZC = (prach_fmt <4)?839:139; - // u = (prach_fmt < 4) ? prach_root_sequence_map0_3[fp->prach_config_common.rootSequenceIndex] : - // prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex]; - - //compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u); - //compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex, - // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, - // fp->frame_type, - // PHY_vars_UE_g[Mod_id][CC_id]->X_u); - - - fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift; - fp->pucch_config_common.nRB_CQI = radioResourceConfigCommon->pucch_ConfigCommon->nRB_CQI; - fp->pucch_config_common.nCS_AN = radioResourceConfigCommon->pucch_ConfigCommon->nCS_AN; - fp->pucch_config_common.n1PUCCH_AN = radioResourceConfigCommon->pucch_ConfigCommon->n1PUCCH_AN; - fp->pdsch_config_common.referenceSignalPower = radioResourceConfigCommon->pdsch_ConfigCommon->referenceSignalPower; - fp->pdsch_config_common.p_b = radioResourceConfigCommon->pdsch_ConfigCommon->p_b; - - - fp->pusch_config_common.n_SB = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.n_SB; - fp->pusch_config_common.hoppingMode = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode; - fp->pusch_config_common.pusch_HoppingOffset = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset; - fp->pusch_config_common.enable64QAM = radioResourceConfigCommon->pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled; - fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = radioResourceConfigCommon->pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift; - - init_ul_hopping(fp); - fp->soundingrs_ul_config_common.enabled_flag = 0; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->present==SoundingRS_UL_ConfigCommon_PR_setup) { - fp->soundingrs_ul_config_common.enabled_flag = 1; - fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_BandwidthConfig; - fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; - fp->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.ackNackSRS_SimultaneousTransmission; - - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_MaxUpPts) - fp->soundingrs_ul_config_common.srs_MaxUpPts = 1; - else - fp->soundingrs_ul_config_common.srs_MaxUpPts = 0; - } - - fp->ul_power_control_config_common.p0_NominalPUSCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUSCH; - fp->ul_power_control_config_common.alpha = radioResourceConfigCommon->uplinkPowerControlCommon->alpha; - fp->ul_power_control_config_common.p0_NominalPUCCH = radioResourceConfigCommon->uplinkPowerControlCommon->p0_NominalPUCCH; - fp->ul_power_control_config_common.deltaPreambleMsg3 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaPreambleMsg3; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1; - fp->ul_power_control_config_common.deltaF_PUCCH_Format1b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format1b; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2 = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2a = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2a; - fp->ul_power_control_config_common.deltaF_PUCCH_Format2b = radioResourceConfigCommon->uplinkPowerControlCommon->deltaFList_PUCCH.deltaF_PUCCH_Format2b; - - fp->maxHARQ_Msg3Tx = radioResourceConfigCommon->rach_ConfigCommon->maxHARQ_Msg3Tx; - - // Now configure some of the Physical Channels - if (radioResourceConfigCommon->antennaInfoCommon) - fp->nb_antennas_tx = (1<antennaInfoCommon->antennaPortsCount); - else - fp->nb_antennas_tx = 1; - - //PHICH - if (radioResourceConfigCommon->antennaInfoCommon) { - fp->phich_config_common.phich_resource = radioResourceConfigCommon->phich_Config->phich_Resource; - fp->phich_config_common.phich_duration = radioResourceConfigCommon->phich_Config->phich_Duration; - } - - //Target CellId - fp->Nid_cell = mobilityControlInfo->targetPhysCellId; - fp->nushift = fp->Nid_cell%6; - - // PUCCH - init_ncs_cell(fp,PHY_vars_UE_g[Mod_id][CC_id]->ncs_cell); - - init_ul_hopping(fp); - - // RNTI - - - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti = mobilityControlInfo->newUE_Identity.buf[0]|(mobilityControlInfo->newUE_Identity.buf[1]<<8); - - LOG_I(PHY,"SET C-RNTI %x %x\n",PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_id]->crnti, - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_id]->crnti); - } - - if(ho_failed) { - LOG_D(PHY,"[UE%d] Handover failed, triggering RACH procedure\n",Mod_id); - memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms,(void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, sizeof(NR_DL_FRAME_PARMS)); - PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_id] = PRACH; - } -} - - -void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id) -{ - - PHY_NR_MEASUREMENTS *phy_meas = &PHY_vars_UE_g[Mod_id][CC_id]->measurements; - int i; - - LOG_I(PHY,"Configuring inter-cell measurements for %d cells, ids: \n",n_adj_cells); - - for (i=0; iframe_parms,PHY_vars_UE_g[Mod_id][CC_id]->lte_gold_table[i+1],adj_cell_id[i]); - } - - phy_meas->n_adj_cells = n_adj_cells; - memcpy((void*)phy_meas->adj_cell_id,(void *)adj_cell_id,n_adj_cells*sizeof(unsigned int)); - -} -*/ - -#if defined(Rel10) || defined(Rel14) -void phy_config_dedicated_scell_ue(uint8_t Mod_id, - uint8_t eNB_index, - SCellToAddMod_r10_t *sCellToAddMod_r10, - int CC_id) { -} -#endif - #if 0 void phy_config_harq_ue(module_id_t Mod_id, int CC_id, - uint8_t eNB_id, + uint8_t gNB_id, uint16_t max_harq_tx) { int num_of_threads,num_of_code_words; PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; for (num_of_threads=0; num_of_threadsulsch[num_of_threads][eNB_id][num_of_code_words]->Mlimit = max_harq_tx; + phy_vars_ue->ulsch[num_of_threads][gNB_id][num_of_code_words]->Mlimit = max_harq_tx; } #endif extern uint16_t beta_cqi[16]; -/* -void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id, - struct PhysicalConfigDedicated *physicalConfigDedicated ) -{ - - static uint8_t first_dedicated_configuration = 0; - PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - - phy_vars_ue->total_TBS[eNB_id]=0; - phy_vars_ue->total_TBS_last[eNB_id]=0; - phy_vars_ue->bitrate[eNB_id]=0; - phy_vars_ue->total_received_bits[eNB_id]=0; - phy_vars_ue->dlsch_errors[eNB_id]=0; - phy_vars_ue->dlsch_errors_last[eNB_id]=0; - phy_vars_ue->dlsch_received[eNB_id]=0; - phy_vars_ue->dlsch_received_last[eNB_id]=0; - phy_vars_ue->dlsch_fer[eNB_id]=0; - - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - - if (physicalConfigDedicated) { - LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, eNB_id); - LOG_D(PHY,"------------------------------------------------------------------------\n"); - - if (physicalConfigDedicated->pdsch_ConfigDedicated) { - phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a=physicalConfigDedicated->pdsch_ConfigDedicated->p_a; - LOG_D(PHY,"pdsch_config_dedicated.p_a %d\n",phy_vars_ue->pdsch_config_dedicated[eNB_id].p_a); - LOG_D(PHY,"\n"); - } - - if (physicalConfigDedicated->pucch_ConfigDedicated) { - if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release) - phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=0; - else { - phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=1; - } - - if (physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) - phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = *physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode; - else - phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode = bundling; - - if ( phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode == multiplexing) - LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = multiplexing\n"); - else - LOG_D(PHY,"pucch_config_dedicated.tdd_AckNackFeedbackMode = bundling\n"); - } - - if (physicalConfigDedicated->pusch_ConfigDedicated) { - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; - phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; - - - LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index); - LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]); - LOG_D(PHY,"\n"); - - - } - - if (physicalConfigDedicated->uplinkPowerControlDedicated) { - - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH = physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUSCH; - phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled= physicalConfigDedicated->uplinkPowerControlDedicated->deltaMCS_Enabled; - phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled= physicalConfigDedicated->uplinkPowerControlDedicated->accumulationEnabled; - phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH= physicalConfigDedicated->uplinkPowerControlDedicated->p0_UE_PUCCH; - phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset= physicalConfigDedicated->uplinkPowerControlDedicated->pSRS_Offset; - phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient= *physicalConfigDedicated->uplinkPowerControlDedicated->filterCoefficient; - LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUSCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUSCH); - LOG_D(PHY,"ul_power_control_dedicated.deltaMCS_Enabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].deltaMCS_Enabled); - LOG_D(PHY,"ul_power_control_dedicated.accumulationEnabled %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].accumulationEnabled); - LOG_D(PHY,"ul_power_control_dedicated.p0_UE_PUCCH %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].p0_UE_PUCCH); - LOG_D(PHY,"ul_power_control_dedicated.pSRS_Offset %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].pSRS_Offset); - LOG_D(PHY,"ul_power_control_dedicated.filterCoefficient %d\n",phy_vars_ue->ul_power_control_dedicated[eNB_id].filterCoefficient); - LOG_D(PHY,"\n"); - } - - if (physicalConfigDedicated->antennaInfo) { - phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); - LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); - switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: - phy_vars_ue->transmission_mode[eNB_id] = 1; - break; - case AntennaInfoDedicated__transmissionMode_tm2: - phy_vars_ue->transmission_mode[eNB_id] = 2; - break; - case AntennaInfoDedicated__transmissionMode_tm3: - phy_vars_ue->transmission_mode[eNB_id] = 3; - break; - case AntennaInfoDedicated__transmissionMode_tm4: - phy_vars_ue->transmission_mode[eNB_id] = 4; - break; - case AntennaInfoDedicated__transmissionMode_tm5: - phy_vars_ue->transmission_mode[eNB_id] = 5; - break; - case AntennaInfoDedicated__transmissionMode_tm6: - phy_vars_ue->transmission_mode[eNB_id] = 6; - break; - case AntennaInfoDedicated__transmissionMode_tm7: - lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); - phy_vars_ue->transmission_mode[eNB_id] = 7; - break; - default: - LOG_E(PHY,"Unknown transmission mode!\n"); - break; - } - } else { - LOG_D(PHY,"[UE %d] Received NULL physicalConfigDedicated->antennaInfo from eNB %d\n",Mod_id, eNB_id); - } - - if (physicalConfigDedicated->schedulingRequestConfig) { - if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) { - phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; - phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; - phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; - - LOG_D(PHY,"scheduling_request_config.sr_PUCCH_ResourceIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - LOG_D(PHY,"scheduling_request_config.sr_ConfigIndex %d\n",phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex); - LOG_D(PHY,"scheduling_request_config.dsr_TransMax %d\n",phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax); - } - - LOG_D(PHY,"------------------------------------------------------------\n"); - - } - - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { - - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0; - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].freqDomainPosition = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_Bandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_HoppingBandwidth = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth; - phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].transmissionComb = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb; - - - LOG_D(PHY,"soundingrs_ul_config_dedicated.srs_ConfigIndex %d\n",phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srs_ConfigIndex); - } - - LOG_D(PHY,"------------------------------------------------------------\n"); - - } - - - if (physicalConfigDedicated->cqi_ReportConfig) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { - // configure PUSCH CQI reporting - phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic; - if ((phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm12) && - (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm30) && - (phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic != rm31)) - LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic); - } - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { - // configure PUCCH CQI reporting - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex; - } - else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) { - // handle release - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; - phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; - } - } - } - - } else { - LOG_D(PHY,"[PHY][UE %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id,eNB_id); - return; - } - - // fill cqi parameters for periodic CQI reporting - get_cqipmiri_params(phy_vars_ue,eNB_id); - - // disable MIB SIB decoding once we are on connected mode - first_dedicated_configuration ++; - if(first_dedicated_configuration > 1) - { - LOG_I(PHY,"Disable SIB MIB decoding \n"); - phy_vars_ue->decode_SIB = 0; - phy_vars_ue->decode_MIB = 0; - } - //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; - if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) - phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; - else - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; - - LOG_I(PHY,"C-RNTI %x %x \n", phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, - phy_vars_ue->pdcch_vars[1][eNB_id]->crnti); - - -}*/ - /*! \brief Helper function to allocate memory for DLSCH data structures. * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize. * \param[in] frame_parms LTE_DL_FRAME_PARMS structure. @@ -604,6 +83,10 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, //pdsch->dl_ch_rho2_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) ); pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + pdsch->dl_ch_ptrs_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); // the allocated memory size is fixed: AssertFatal( fp->nb_antennas_rx <= 2, "nb_antennas_rx > 2" ); @@ -624,6 +107,10 @@ void phy_init_nr_ue__PDSCH(NR_UE_PDSCH *const pdsch, //pdsch->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->dl_ch_magr0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + pdsch->ptrs_re_per_slot[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * 14); + pdsch->ptrs_phase_per_slot[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 ); + pdsch->dl_ch_ptrs_estimates_ext[idx]= (int32_t *)malloc16_clear( sizeof(int32_t) * num); } } } @@ -638,7 +125,7 @@ void phy_init_nr_ue_PUSCH(NR_UE_PUSCH *const pusch, } int init_nr_ue_signal(PHY_VARS_NR_UE *ue, - int nb_connected_eNB, + int nb_connected_gNB, uint8_t abstraction_flag) { // create shortcuts NR_DL_FRAME_PARMS *const fp = &ue->frame_parms; @@ -646,7 +133,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, NR_UE_PBCH **const pbch_vars = ue->pbch_vars; NR_UE_PRACH **const prach_vars = ue->prach_vars; int i,j,k,l,slot,symb,q; - int eNB_id; + int gNB_id; int th_id; 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 @@ -656,12 +143,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, fp->nb_antennas_rx=1; // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig; // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; - printf("Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx); + LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx); //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST); phy_init_nr_top(ue); // many memory allocation sizes are hard coded - AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[eNB_id]" ); - AssertFatal( nb_connected_eNB <= NUMBER_OF_CONNECTED_eNB_MAX, "n_connected_eNB is too large" ); + AssertFatal( fp->nb_antennas_rx <= 2, "hard coded allocation for ue_common_vars->dl_ch_estimates[gNB_id]" ); + AssertFatal(nb_connected_gNB <= NUMBER_OF_CONNECTED_gNB_MAX, "n_connected_gNB is too large" ); // init phy_vars_ue for (i=0; i<4; i++) { @@ -670,13 +157,17 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->rx_gain_byp[i] = 120; } - ue->n_connected_eNB = nb_connected_eNB; + ue->n_connected_gNB = nb_connected_gNB; - for(eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - ue->total_TBS[eNB_id] = 0; - ue->total_TBS_last[eNB_id] = 0; - ue->bitrate[eNB_id] = 0; - ue->total_received_bits[eNB_id] = 0; + for(gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { + ue->total_TBS[gNB_id] = 0; + ue->total_TBS_last[gNB_id] = 0; + ue->bitrate[gNB_id] = 0; + ue->total_received_bits[gNB_id] = 0; + + ue->ul_time_alignment[gNB_id].apply_ta = 0; + ue->ul_time_alignment[gNB_id].ta_frame = -1; + ue->ul_time_alignment[gNB_id].ta_slot = -1; } // init NR modulation lookup tables nr_generate_modulation_table(); @@ -684,9 +175,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, /////////////////////////PUSCH init///////////////////////// /////////// for (th_id = 0; th_id < RX_NB_TH_MAX; th_id++) { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - ue->pusch_vars[th_id][eNB_id] = (NR_UE_PUSCH *)malloc16(sizeof(NR_UE_PUSCH)); - phy_init_nr_ue_PUSCH( ue->pusch_vars[th_id][eNB_id], fp ); + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { + ue->pusch_vars[th_id][gNB_id] = (NR_UE_PUSCH *)malloc16(sizeof(NR_UE_PUSCH)); + phy_init_nr_ue_PUSCH( ue->pusch_vars[th_id][gNB_id], fp ); } } @@ -785,41 +276,75 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } } + //PDCCH DMRS init (eNB offset = 0) + ue->nr_gold_pdcch[0] = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); + uint32_t ***pdcch_dmrs = ue->nr_gold_pdcch[0]; + AssertFatal(pdcch_dmrs!=NULL, "NR init: pdcch_dmrs malloc failed\n"); + + for (int slot=0; slotslots_per_frame; slot++) { + pdcch_dmrs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); + AssertFatal(pdcch_dmrs[slot]!=NULL, "NR init: pdcch_dmrs for slot %d - malloc failed\n", slot); + + for (int symb=0; symbsymbols_per_slot; symb++) { + pdcch_dmrs[slot][symb] = (uint32_t *)malloc16(NR_MAX_PDCCH_DMRS_INIT_LENGTH_DWORD*sizeof(uint32_t)); + AssertFatal(pdcch_dmrs[slot][symb]!=NULL, "NR init: pdcch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); + } + } + + //PDSCH DMRS init (eNB offset = 0) + ue->nr_gold_pdsch[0] = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); + uint32_t ****pdsch_dmrs = ue->nr_gold_pdsch[0]; + + for (int slot=0; slotslots_per_frame; slot++) { + pdsch_dmrs[slot] = (uint32_t ***)malloc16(fp->symbols_per_slot*sizeof(uint32_t **)); + AssertFatal(pdsch_dmrs[slot]!=NULL, "NR init: pdsch_dmrs for slot %d - malloc failed\n", slot); + + for (int symb=0; symbsymbols_per_slot; symb++) { + pdsch_dmrs[slot][symb] = (uint32_t **)malloc16(NR_MAX_NB_CODEWORDS*sizeof(uint32_t *)); + AssertFatal(pdsch_dmrs[slot][symb]!=NULL, "NR init: pdsch_dmrs for slot %d symbol %d - malloc failed\n", slot, symb); + + for (int q=0; qn_connected_eNB; eNB_id++) { + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { for (th_id=0; th_idpdsch_vars[th_id][eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); + ue->pdsch_vars[th_id][gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); } for (th_id=0; th_idpdcch_vars[th_id][eNB_id] = (NR_UE_PDCCH *)malloc16_clear(sizeof(NR_UE_PDCCH)); + ue->pdcch_vars[th_id][gNB_id] = (NR_UE_PDCCH *)malloc16_clear(sizeof(NR_UE_PDCCH)); } - prach_vars[eNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH)); - pbch_vars[eNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH)); + prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH)); + pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH)); if (abstraction_flag == 0) { for (th_id=0; th_idpdsch_vars[th_id][eNB_id], fp ); + phy_init_nr_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp ); } for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12); - ue->pdsch_vars[th_id][eNB_id]->llr_shifts_p = ue->pdsch_vars[0][eNB_id]->llr_shifts; - ue->pdsch_vars[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); - ue->pdsch_vars[th_id][eNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); - ue->pdsch_vars[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) ); - ue->pdsch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][gNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12); + ue->pdsch_vars[th_id][gNB_id]->llr_shifts_p = ue->pdsch_vars[0][gNB_id]->llr_shifts; + ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t)); + ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t)); + ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear(sizeof(int16_t *)); + ue->pdsch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16_clear(fp->nb_antennas_rx*sizeof(int32_t *)); } for (int i=0; inb_antennas_rx; i++) { for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + ue->pdsch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12)); } } for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); } for (i=0; inb_antennas_rx; i++) @@ -828,7 +353,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, const size_t num = 7*2*fp->N_RB_DL*12+4; for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num); } } @@ -836,10 +361,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, for (k=0; k<8; k++) { //harq_pid for (l=0; l<8; l++) { //round for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); } for (int i=0; inb_antennas_rx; i++) @@ -847,10 +372,10 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, const int idx = (j<<1)+i; for (th_id=0; th_idpdsch_vars[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - ue->pdsch_vars[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); - ue->pdsch_vars[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) ); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12)); + ue->pdsch_vars[th_id][gNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12)); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12)); + ue->pdsch_vars[th_id][gNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear(7*2*sizeof(int32_t)*(fp->N_RB_DL*12)); } } } @@ -858,72 +383,72 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE for (th_id=0; th_idpdcch_vars[th_id][eNB_id]->llr = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - ue->pdcch_vars[th_id][eNB_id]->llr16 = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - ue->pdcch_vars[th_id][eNB_id]->wbar = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); - ue->pdcch_vars[th_id][eNB_id]->e_rx = (int16_t *)malloc16_clear( 4*2*100*12 ); - ue->pdcch_vars[th_id][eNB_id]->rxdataF_comp = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->rho = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->rxdataF_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) ); + ue->pdcch_vars[th_id][gNB_id]->llr = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t)); + ue->pdcch_vars[th_id][gNB_id]->llr16 = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t)); + ue->pdcch_vars[th_id][gNB_id]->wbar = (int16_t *)malloc16_clear(2*4*100*12*sizeof(uint16_t)); + ue->pdcch_vars[th_id][gNB_id]->e_rx = (int16_t *)malloc16_clear(4*2*100*12 ); + ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16(fp->nb_antennas_rx*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); // Channel estimates - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); for (i=0; inb_antennas_rx; i++) { - ue->pdcch_vars[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4) ); + ue->pdcch_vars[th_id][gNB_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(100*12*4)); for (j=0; j<4; j++) { int idx = (j<<1) + i; - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 ); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*fp->ofdm_symbol_size*2); // size_t num = 7*2*fp->N_RB_DL*12; size_t num = 4*273*12; // 4 symbols, 100 PRBs, 12 REs per PRB - ue->pdcch_vars[th_id][eNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_rho_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - ue->pdcch_vars[th_id][eNB_id]->rxdataF_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - ue->pdcch_vars[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); + ue->pdcch_vars[th_id][gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_rho_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num); + ue->pdcch_vars[th_id][gNB_id]->rxdataF_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num); + ue->pdcch_vars[th_id][gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t) * num); } } } // PBCH - pbch_vars[eNB_id]->rxdataF_ext = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - 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)) ); + pbch_vars[gNB_id]->rxdataF_ext = (int32_t **)malloc16(fp->nb_antennas_rx*sizeof(int32_t *)); + pbch_vars[gNB_id]->rxdataF_comp = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + pbch_vars[gNB_id]->dl_ch_estimates = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + pbch_vars[gNB_id]->dl_ch_estimates_ext = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + pbch_vars[gNB_id]->dl_ch_estimates_time = (int32_t **)malloc16_clear(8*sizeof(int32_t *)); + pbch_vars[gNB_id]->llr = (int16_t *)malloc16_clear(1920); // + prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear(sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12))); + prach_vars[gNB_id]->prach = (int16_t *)malloc16_clear(sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12))); for (i=0; inb_antennas_rx; i++) { - pbch_vars[eNB_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); + pbch_vars[gNB_id]->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*20*12*4 ); for (j=0; j<4; j++) {//fp->nb_antennas_tx;j++) { 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 ); + pbch_vars[gNB_id]->rxdataF_comp[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*20*12*4); + pbch_vars[gNB_id]->dl_ch_estimates[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size)); + pbch_vars[gNB_id]->dl_ch_estimates_time[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*7*2*sizeof(int)*(fp->ofdm_symbol_size)); + pbch_vars[gNB_id]->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear(sizeof(int32_t)*20*12*4); } } } - pbch_vars[eNB_id]->decoded_output = (uint8_t *)malloc16_clear( 64 ); + pbch_vars[gNB_id]->decoded_output = (uint8_t *)malloc16_clear(64); } // initialization for the last instance of pdsch_vars (used for MU-MIMO) for (th_id=0; th_idpdsch_vars[th_id][eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) ); + ue->pdsch_vars[th_id][gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); } if (abstraction_flag == 0) { for (th_id=0; th_idpdsch_vars[th_id][eNB_id], fp ); - ue->pdsch_vars[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); - ue->pdsch_vars[th_id][eNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) ); + //phy_init_lte_ue__PDSCH( ue->pdsch_vars[th_id][gNB_id], fp ); + ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t)); + ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear((8*(3*8*8448))*sizeof(int16_t)); } } else { //abstraction == 1 ue->sinr_dB = (double *) malloc16_clear( fp->N_RB_DL*12*sizeof(double) ); @@ -952,7 +477,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, void init_nr_ue_transport(PHY_VARS_NR_UE *ue, int abstraction_flag) { - for (int i=0; idlsch[k][i][j] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS,ue->frame_parms.N_RB_DL, abstraction_flag))!=NULL,"Can't get ue dlsch structures\n"); @@ -969,6 +494,64 @@ void init_nr_ue_transport(PHY_VARS_NR_UE *ue, //ue->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1; ue->dlsch_MCH[0] = new_nr_ue_dlsch(1,NR_MAX_DLSCH_HARQ_PROCESSES,NSOFT,MAX_LDPC_ITERATIONS_MBSFN,ue->frame_parms.N_RB_DL,0); + + for(int i=0; i<5; i++) + ue->dl_stats[i] = 0; +} + + +void init_N_TA_offset(PHY_VARS_NR_UE *ue){ + + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + + if (fp->frame_type == FDD) { + ue->N_TA_offset = 0; + } else { + int N_RB = fp->N_RB_DL; + int N_TA_offset = fp->ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 + double factor = 1; + switch (fp->numerology_index) { + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); + if (N_RB <= 25) factor = .25; // 7.68 Ms/s + else if (N_RB <=50) factor = .5; // 15.36 Ms/s + else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s + else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s + else AssertFatal(1==0, "Too many PRBS for mu=0\n"); + break; + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); + if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s + else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + break; + case 2: //60 kHz scs + AssertFatal(1==0, "scs_common should not be 60 kHz\n"); + break; + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); + break; + case 4: //240 kHz scs + AssertFatal(1==0, "scs_common should not be 60 kHz\n"); + if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s + else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s + else AssertFatal(1==0, "N_RB %d is too big for curretn FR2 implementation\n", N_RB); + break; + + if (N_RB == 100) + ue->N_TA_offset = 624; + else if (N_RB == 50) + ue->N_TA_offset = 624/2; + else if (N_RB == 25) + ue->N_TA_offset = 624/4; + } + + if (fp->threequarter_fs == 1) + factor = factor*.75; + + ue->N_TA_offset = (int)(N_TA_offset * factor); + + LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", ue->Mod_id, ue->N_TA_offset, factor, fp->ul_CarrierFreq, N_RB); + } } void phy_init_nr_top(PHY_VARS_NR_UE *ue) { @@ -988,57 +571,3 @@ void phy_init_nr_top(PHY_VARS_NR_UE *ue) { //init_scrambling_lut(); //set_taus_seed(1328); } - -void set_default_frame_parms_single(nfapi_nr_config_request_t *config, - NR_DL_FRAME_PARMS *frame_parms) { - /* Set some default values that may be overwritten while reading options */ - frame_parms = (NR_DL_FRAME_PARMS*) malloc(sizeof(NR_DL_FRAME_PARMS)); - config = (nfapi_nr_config_request_t*) malloc(sizeof(nfapi_nr_config_request_t)); - config->subframe_config.numerology_index_mu.value =1; - config->subframe_config.duplex_mode.value = 1; //FDD - config->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL - config->rf_config.dl_carrier_bandwidth.value = 100; - config->rf_config.ul_carrier_bandwidth.value = 100; - config->sch_config.physical_cell_id.value = 0; - - frame_parms->frame_type = FDD; - //frame_parms[CC_id]->tdd_config_S = 0; - frame_parms->N_RB_DL = 106; - frame_parms->N_RB_UL = 106; - frame_parms->Ncp = NORMAL; - //frame_parms[CC_id]->Ncp_UL = NORMAL; - frame_parms->Nid_cell = 0; - //frame_parms[CC_id]->num_MBSFN_config = 0; - frame_parms->nb_antenna_ports_gNB = 1; - frame_parms->nb_antennas_tx = 1; - frame_parms->nb_antennas_rx = 1; - - //frame_parms[CC_id]->nushift = 0; - - ///frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; - //frame_parms[CC_id]->phich_config_common.phich_duration = normal; - - // UL RS Config - /*frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 1;//n_DMRS1 set to 0 - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 1; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; - frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; - - frame_parms[CC_id]->pusch_config_common.n_SB = 1; - frame_parms[CC_id]->pusch_config_common.hoppingMode = 0; - frame_parms[CC_id]->pusch_config_common.pusch_HoppingOffset = 0; - frame_parms[CC_id]->pusch_config_common.enable64QAM = 0; - - frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; - frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;*/ - - // NR: Init to legacy LTE 20Mhz params - frame_parms->numerology_index = 0; - frame_parms->ttis_per_subframe = 1; - frame_parms->slots_per_tti = 2; - - -} diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 6045930b17..ba4147e5cd 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -27,8 +27,6 @@ uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16}; - - int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) { @@ -43,38 +41,32 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) int case_E[8] = {8, 12, 16, 20, 32, 36, 40, 44}; switch(mu) { - - case NR_MU_0: // case A - n = i_ssb >> 1; - symbol = case_AC[i_ssb % 2] + 14*n; - break; - - case NR_MU_1: - if (type == 1){ // case B - n = i_ssb >> 2; - symbol = case_BD[i_ssb % 4] + 28*n; - } - if (type == 2){ // case C - n = i_ssb >> 1; - symbol = case_AC[i_ssb % 2] + 14*n; - } - break; - - case NR_MU_3: // case D - n_temp = i_ssb >> 2; - n = n_temp + (n_temp >> 2); - symbol = case_BD[i_ssb % 4] + 28*n; - break; - - case NR_MU_4: // case E - n_temp = i_ssb >> 3; - n = n_temp + (n_temp >> 2); - symbol = case_E[i_ssb % 8] + 56*n; - break; - - - default: - AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); + case NR_MU_0: // case A + n = i_ssb >> 1; + symbol = case_AC[i_ssb % 2] + 14*n; + break; + case NR_MU_1: + if (type == 1){ // case B + n = i_ssb >> 2; + symbol = case_BD[i_ssb % 4] + 28*n; + } + if (type == 2){ // case C + n = i_ssb >> 1; + symbol = case_AC[i_ssb % 2] + 14*n; + } + break; + case NR_MU_3: // case D + n_temp = i_ssb >> 2; + n = n_temp + (n_temp >> 2); + symbol = case_BD[i_ssb % 4] + 28*n; + break; + case NR_MU_4: // case E + n_temp = i_ssb >> 3; + n = n_temp + (n_temp >> 2); + symbol = case_E[i_ssb % 8] + 56*n; + break; + default: + AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); } if (half_frame_index) @@ -85,6 +77,7 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp) void set_scs_parameters (NR_DL_FRAME_PARMS *fp, int mu, uint16_t bw) { + switch(mu) { case NR_MU_0: //15kHz scs @@ -233,6 +226,20 @@ uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) return samp_count; } + +uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp) +{ + uint32_t slot_idx = 0; + int samples_till_the_slot = 0; + timestamp_rx = timestamp_rx%fp->samples_per_frame; + + while (timestamp_rx > samples_till_the_slot) { + samples_till_the_slot += fp->get_samples_per_slot(slot_idx,fp); + slot_idx++; + } + return slot_idx; +} + uint32_t get_samples_slot_timestamp(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead) { uint32_t samp_count = 0; @@ -251,13 +258,15 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, NR_DL_FRAME_PARMS *fp) { + AssertFatal (cfg != NULL, "%s %s:%i Null pointer to cfg %p!\n", __FUNCTION__, __FILE__, __LINE__, cfg); + fp->frame_type = cfg->cell_config.frame_duplex_type.value; fp->L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; fp->N_RB_DL = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; fp->N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; int Ncp = NFAPI_CP_NORMAL; - int mu = cfg!= NULL ? cfg->ssb_config.scs_common.value : 0; + int mu = cfg->ssb_config.scs_common.value; #if DISABLE_LOG_X printf("Initializing frame parms for mu %d, N_RB %d, Ncp %d\n",mu, fp->N_RB_DL, Ncp); @@ -275,9 +284,9 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, fp->slots_per_frame = 10* fp->slots_per_subframe; - fp->nb_antenna_ports_gNB = 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->nb_antenna_ports_gNB = cfg->carrier_config.num_tx_ant.value;// It corresponds to pdsch_AntennaPorts + fp->nb_antennas_rx = cfg->carrier_config.num_rx_ant.value; // It denotes the number of rx antennas at gNB + fp->nb_antennas_tx = 1; // It corresponds to the number of UE Tx antennas 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; @@ -289,6 +298,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, (fp->nb_prefix_samples + fp->ofdm_symbol_size) * (fp->symbols_per_slot * fp->slots_per_subframe - 2); fp->get_samples_per_slot = &get_samples_per_slot; fp->get_samples_slot_timestamp = &get_samples_slot_timestamp; + fp->get_slot_from_timestamp = &get_slot_from_timestamp; fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; @@ -305,7 +315,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, } fp->N_ssb = 0; - int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value; + int num_tx_ant = cfg->carrier_config.num_tx_ant.value; for (int p=0; pN_ssb += ((fp->L_ssb >> (63-p)) & 0x01); @@ -315,10 +325,23 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, } int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, - fapi_nr_config_request_t* config, - int Ncp) + fapi_nr_config_request_t* config, + uint16_t nr_band) { + uint8_t nb_ant_ports_gNB = 1; + uint8_t tdd_cfg = 3; + uint8_t Nid_cell = 0; + int Ncp = NORMAL; + + // default values until overwritten by RRCConnectionReconfiguration + fp->nb_antenna_ports_gNB = nb_ant_ports_gNB; + fp->tdd_config = tdd_cfg; + fp->Nid_cell = Nid_cell; + fp->nr_band = nr_band; + + LOG_I(PHY, "Initializing frame parms: set nb_antenna_ports_gNB %d, tdd_config, %d, Nid_cell %d\n", fp->nb_antenna_ports_gNB, fp->tdd_config, fp->Nid_cell); + uint64_t dl_bw_khz = (12*config->carrier_config.dl_grid_size[config->ssb_config.scs_common])*(15<ssb_config.scs_common); fp->dl_CarrierFreq = ((dl_bw_khz>>1) + config->carrier_config.dl_frequency)*1000 ; @@ -330,11 +353,15 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index]; int32_t uplink_frequency_offset = 0; + get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset); + get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type); + uplink_frequency_offset *= 1000; - get_band(fp->dl_CarrierFreq, &fp->nr_band, &uplink_frequency_offset, &fp->frame_type); + LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset); AssertFatal(fp->frame_type==config->cell_config.frame_duplex_type, "Invalid duplex type in config request file for band %d\n", fp->nr_band); - AssertFatal(fp->ul_CarrierFreq==(fp->dl_CarrierFreq+uplink_frequency_offset), "Disagreement in uplink frequency for band %d\n", fp->nr_band); + + AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + uplink_frequency_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + uplink_frequency_offset); #if DISABLE_LOG_X printf("Initializing UE frame parms for mu %d, N_RB %d, Ncp %d\n",fp->numerology_index, fp->N_RB_DL, Ncp); @@ -350,11 +377,6 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, set_scs_parameters(fp,fp->numerology_index,config->carrier_config.dl_bandwidth); fp->slots_per_frame = 10* fp->slots_per_subframe; - - fp->nb_antenna_ports_gNB = 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; fp->samples_per_frame_wCP = 10 * fp->samples_per_subframe_wCP; @@ -385,7 +407,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->Lmax = 64; } - fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[1].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; + fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; fp->N_ssb = 0; for (int p=0; pLmax; p++) diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index 1862d5f8e0..9c474264c8 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -394,9 +394,10 @@ 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); 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,fapi_nr_config_request_t *config,int Ncp); +int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band); 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); +void init_N_TA_offset(PHY_VARS_NR_UE *ue); void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); int phy_init_nr_gNB(PHY_VARS_gNB *gNB, unsigned char is_secondary_gNB, unsigned char abstraction_flag); void nr_phy_config_request(NR_PHY_Config_t *gNB); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c index a881773910..2d79158920 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c @@ -47,6 +47,7 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB, uint32_t rb; int32_t *ul_ch; int32_t n0_power_tot; + int64_t n0_power_tot2; int len; int offset; // noise measurements @@ -75,43 +76,47 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB, } + n0_power_tot2=0; + int nb_rb=0; for (rb=0; rbN_RB_UL; rb++) { - n0_power_tot=0; + n0_power_tot=0; + int offset0= (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; + if ((rb_mask[rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe + nb_rb++; for (aarx=0; aarxnb_antennas_rx; aarx++) { - + measurements->n0_subband_power[aarx][rb] = 0; + for (int s=0;s<14-(frame_parms->Ncp<<1);s++) { // select the 7th symbol in an uplink subframe - offset = (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; - offset += (7*frame_parms->ofdm_symbol_size); - ul_ch = &common_vars->rxdataF[aarx][offset]; - len = 12; + offset = offset0 + (s*frame_parms->ofdm_symbol_size); + ul_ch = &common_vars->rxdataF[aarx][offset]; + len = 12; // just do first half of middle PRB for odd number of PRBs - if (((frame_parms->N_RB_UL&1) == 1) && - (rb==(frame_parms->N_RB_UL>>1))) { - len=6; - } - if (clear == 1) - measurements->n0_subband_power[aarx][rb]=0; + if (((frame_parms->N_RB_UL&1) == 1) && + (rb==(frame_parms->N_RB_UL>>1))) { + len=6; + } - AssertFatal(ul_ch, "RX signal buffer (freq) problem"); + AssertFatal(ul_ch, "RX signal buffer (freq) problem"); - measurements->n0_subband_power[aarx][rb] = signal_energy_nodc(ul_ch,len); - //((k1*(signal_energy_nodc(ul_ch,len))) - // + (k2*measurements->n0_subband_power[aarx][rb])); + measurements->n0_subband_power[aarx][rb] += signal_energy_nodc(ul_ch,len); - measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]); - // printf("subframe %d (%d): eNB %d, aarx %d, rb %d len %d: energy %d (%d dB)\n",subframe,offset,eNB_id,aarx,rb,len,signal_energy_nodc(ul_ch,len), - // measurements->n0_subband_power_dB[aarx][rb]); - n0_power_tot += measurements->n0_subband_power[aarx][rb]; + } + measurements->n0_subband_power[aarx][rb]/=(14-(frame_parms->Ncp<<1)); + measurements->n0_subband_power_dB[aarx][rb] = dB_fixed(measurements->n0_subband_power[aarx][rb]); + n0_power_tot += measurements->n0_subband_power[aarx][rb]; + } - - measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot); + n0_power_tot/=frame_parms->nb_antennas_rx; + n0_power_tot2 += n0_power_tot; + measurements->n0_subband_power_tot_dB[rb] = dB_fixed(n0_power_tot/frame_parms->nb_antennas_rx); measurements->n0_subband_power_tot_dBm[rb] = measurements->n0_subband_power_tot_dB[rb] - eNB->rx_total_gain_dB - dB_fixed(frame_parms->N_RB_UL); } } + if (nb_rb>0) measurements->n0_subband_power_avg_dB = dB_fixed(n0_power_tot2/nb_rb); } void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB, diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 755111feb8..1d1b16e036 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -786,33 +786,38 @@ int16_t lte_ul_freq_offset_estimation(LTE_DL_FRAME_PARMS *frame_parms, Ravg[0]=0; Ravg[1]=0; int16_t iv, rv, phase_idx = 0; - __m128i avg128U1, avg128U2, R[3], mmtmpD0, mmtmpD1, mmtmpD2, mmtmpD3; + __m128i R[3], mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; + __m128 avg128U1, avg128U2; // 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) - avg128U1 = _mm_setzero_si128(); - avg128U2 = _mm_setzero_si128(); + avg128U1 = _mm_setzero_ps(); + avg128U2 = _mm_setzero_ps(); for (rb=0; rbharq_processes[harq_pid]->round++; ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3; ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; + ulsch->harq_processes[harq_pid]->Or1 = 0; + ulsch->harq_processes[harq_pid]->Or2 = 0; } ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti; diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 8c07421b7e..347fbb026b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2242,16 +2242,12 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, MIMO_mode_t mimo_mode = -1; uint8_t mprime=0,Ns; int8_t lprime=-1; - int aa=0; #ifdef DEBUG_DLSCH_MODULATION uint8_t Nl0; //= dlsch0_harq->Nl; uint8_t Nl1; #endif - int ru_id; - RU_t *ru; - int eNB_id; if ((dlsch0 != NULL) && (dlsch1 != NULL)){ @@ -2432,11 +2428,13 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, } // mapping ue specific beamforming weights from UE specified DLSCH structure to RU beam weights for the eNB - for (ru_id=0;ru_idnum_eNB;eNB_id++){ + for (int eNB_id=0;eNB_idnum_eNB;eNB_id++){ if (phy_vars_eNB == ru->eNB_list[eNB_id]) { - for (aa=0;aanb_tx;aa++){ + for (int aa=0;aanb_tx;aa++){ LOG_I(PHY,"ru_id:%d eNB_id:%d aa:%d memcpy(ru->beam_weights, dlsch0->ue_spec_bf_weights[ru_id][0],)\n", ru_id, eNB_id, aa); memcpy(ru->beam_weights[eNB_id][5][aa], dlsch0->ue_spec_bf_weights[ru_id][0], @@ -2445,6 +2443,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, } } } + */ } diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index a843fc1fd7..95ad420028 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -49,7 +49,7 @@ void send_IF4p5(RU_t *ru, LTE_DL_FRAME_PARMS *fp = ru->frame_parms; int32_t **txdataF = ru->common.txdataF_BF; int32_t **rxdataF = ru->common.rxdataF; - int16_t **prach_rxsigF = ru->prach_rxsigF; + int16_t **prach_rxsigF = ru->prach_rxsigF[0]; int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br; void *tx_buffer = ru->ifbuffer.tx[subframe&1]; void *tx_buffer_prach = ru->ifbuffer.tx_prach; @@ -276,7 +276,7 @@ void recv_IF4p5(RU_t *ru, LTE_DL_FRAME_PARMS *fp = ru->frame_parms; int32_t **txdataF = ru->common.txdataF_BF; int32_t **rxdataF = ru->common.rxdataF; - int16_t **prach_rxsigF = ru->prach_rxsigF; + int16_t **prach_rxsigF = ru->prach_rxsigF[0]; int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br; void *rx_buffer = ru->ifbuffer.rx; uint16_t element_id; diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c index 1e0dd9db1b..f39f3ef872 100644 --- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c @@ -1070,6 +1070,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 ); if (packet_type == IF5_RRH_GW_DL) { if (eth->compression == ALAW_COMPRESS) { + AssertFatal(1==0,"IF5 compression needs reworking\n"); +/* if (eth->flags == ETH_RAW_MODE) { data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); } else { @@ -1100,28 +1102,31 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); } +*/ } else if (eth->compression == NO_COMPRESS) { - for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti]; + for (i=0; i < ru->nb_tx; i++) + txp[i] = (int32_t*)&ru->common.txdata[i][subframe*fp->samples_per_tti]; for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_comp); - ru->ifdevice.trx_write_func(&ru->ifdevice, - (proc_timestamp + packet_id*spp_eth), - (void**)txp, - spp_eth, - fp->nb_antennas_tx, - 0); - clock_gettime( CLOCK_MONOTONIC, &end_comp); - LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); - for (i=0; i < fp->nb_antennas_tx; i++) - txp[i] += spp_eth; + for (int aid=0; aidnb_tx;aid++) { + //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); + clock_gettime( CLOCK_MONOTONIC, &start_comp); + ru->ifdevice.trx_write_func2(&ru->ifdevice, + (proc_timestamp + packet_id*spp_eth-500)*(30720/spsf), + (void*)txp[aid], + spp_eth, + aid, + 0); + LOG_D(HW,"SF %d : packet %d, TS %llu\n",subframe,packet_id,(unsigned long long)(proc_timestamp+packet_id*spp_eth)); + clock_gettime( CLOCK_MONOTONIC, &end_comp); + LOG_D(HW,"[SF %d] IF_Write_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 0 ); + txp[aid] += spp_eth; - } + } + } } } else if (packet_type == IF5_RRH_GW_UL) { if (eth->compression == ALAW_COMPRESS) { @@ -1131,8 +1136,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES); } for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); + //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_comp); for (i=0; i < fp->nb_antennas_rx; i++) { for (element_id=0; element_id< spp_eth; element_id++){ @@ -1142,8 +1147,8 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t } clock_gettime( CLOCK_MONOTONIC, &end_comp); LOG_D(HW,"[SF %d] Compress_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_comp, end_comp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF, 0 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_IF0, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_comp); ru->ifdevice.trx_write_func(&ru->ifdevice, (proc_timestamp + packet_id*spp_eth), @@ -1310,9 +1315,9 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16_t packet_type) { LTE_DL_FRAME_PARMS *fp=ru->frame_parms; - int32_t *txp[fp->nb_antennas_tx], *rxp[fp->nb_antennas_rx]; + int32_t *txp[ru->nb_tx], *rxp[ru->nb_rx]; - uint16_t packet_id=0, i=0, element_id=0; + uint16_t packet_id=0, i=0; #ifdef DEBUG_UL_MOBIPASS //int8_t dummy_buffer_rx[fp->samples_per_tti*2]; uint8_t rxe; @@ -1321,11 +1326,12 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 int32_t spp_eth = (int32_t) ru->ifdevice.openair0_cfg->samples_per_packet; int32_t spsf = (int32_t) ru->ifdevice.openair0_cfg->samples_per_frame/10; - void *alaw_buffer = ru->ifbuffer.rx; - uint16_t *data_block = NULL; - uint16_t *j = NULL; - openair0_timestamp timestamp[spsf / spp_eth]; + openair0_timestamp timestamp[ru->nb_rx*spsf / spp_eth]; + long timein[ru->nb_rx*spsf/spp_eth]; + long timeout[ru->nb_rx*spsf/spp_eth]; + struct timespec if_time; + memset(timestamp, 0, sizeof(timestamp)); eth_state_t *eth = (eth_state_t*) (ru->ifdevice.priv); @@ -1333,6 +1339,9 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 if (packet_type == IF5_RRH_GW_DL) { if (eth->compression == ALAW_COMPRESS) { + AssertFatal(1==0,"IF5 compression needs reworking\n"); + +/* if (eth->flags == ETH_RAW_MODE) { data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); } else { @@ -1364,13 +1373,14 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); } +*/ } else if (eth->compression == NO_COMPRESS) { for (i=0; i < fp->nb_antennas_tx; i++) txp[i] = (void*)&ru->common.txdata[i][subframe*fp->samples_per_tti]; for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); + //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID, packet_id ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); clock_gettime( CLOCK_MONOTONIC, &start_decomp); ru->ifdevice.trx_read_func(&ru->ifdevice, ×tamp[packet_id], @@ -1379,7 +1389,7 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 fp->nb_antennas_tx); clock_gettime( CLOCK_MONOTONIC, &end_decomp); LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); for (i=0; i < fp->nb_antennas_tx; i++) txp[i] += spp_eth; @@ -1389,6 +1399,8 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 } else if (packet_type == IF5_RRH_GW_UL) { if (eth->compression == ALAW_COMPRESS) { + AssertFatal(1==0,"IF5 compression needs reworking\n"); +/* if (eth->flags == ETH_RAW_MODE) { data_block = (uint16_t*)(alaw_buffer + APP_HEADER_SIZE_BYTES + MAC_HEADER_SIZE_BYTES); } else { @@ -1419,197 +1431,55 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16 LOG_D(HW,"[SF %d] Decomperss_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF, 0 ); } +*/ } else if (eth->compression == NO_COMPRESS) { - for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] = (void*)&ru->common.rxdata[i][subframe*fp->samples_per_tti]; - - for (packet_id=0; packet_id < spsf / spp_eth; packet_id++) { - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); - clock_gettime( CLOCK_MONOTONIC, &start_decomp); - ru->ifdevice.trx_read_func(&ru->ifdevice, + int16_t temp_rx[spp_eth*2] __attribute__((aligned(32))); + for (i=0; i < ru->nb_rx; i++) + rxp[i] = &ru->common.rxdata[i][subframe*fp->samples_per_tti]; + int aid; + int firstTS=1; + openair0_timestamp oldTS=0; + + for (packet_id=0; packet_id < ru->nb_rx*spsf / spp_eth; packet_id++) { + //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID, packet_id ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 1 ); + clock_gettime( CLOCK_MONOTONIC, &if_time); + timein[packet_id] = if_time.tv_nsec; + ru->ifdevice.trx_read_func2(&ru->ifdevice, ×tamp[packet_id], - (void**)rxp, + (void*)temp_rx, spp_eth, - fp->nb_antennas_rx); + &aid); + clock_gettime( CLOCK_MONOTONIC, &if_time); + timeout[packet_id] = if_time.tv_nsec; + timestamp[packet_id] /= (30720/spsf); + LOG_D(PHY,"subframe %d: Received packet %d: aid %d, TS %llu, oldTS %llu, diff %lld, \n",subframe,packet_id,aid,(unsigned long long)timestamp[packet_id],(unsigned long long)oldTS,(unsigned long long)(timestamp[packet_id]-timestamp[0])); + if (aid==0) { + if (firstTS==1) firstTS=0; + else if (oldTS + 256 != timestamp[packet_id]) { + LOG_I(PHY,"oldTS %llu, newTS %llu, diff %llu, timein %lu, timeout %lu\n",(long long unsigned int)oldTS,(long long unsigned int)timestamp[packet_id],(long long unsigned int)timestamp[packet_id]-oldTS,timein[packet_id],timeout[packet_id]); + for (int i=0;i<=packet_id;i++) LOG_I(PHY,"packet %d TS %llu, timein %lu, timeout %lu\n",i,(long long unsigned int)timestamp[i],timein[i],timeout[i]); + AssertFatal(1==0,"fronthaul problem\n"); + } + + oldTS = timestamp[packet_id]; + } + + + // HYPOTHESIS: first packet per subframe has lowest timestamp of subframe + // should detect out of order and act accordingly .... + AssertFatal(aid==0 || aid==1,"aid %d != 0 or 1\n",aid); + //LOG_I(PHY,"rxp[%d] %p, dest %p, offset %d (%lld,%lld)\n",aid,rxp[aid],rxp[aid]+(timestamp[packet_id]-timestamp[0]),(timestamp[packet_id]-timestamp[0]),timestamp[packet_id],timestamp[0]); + memcpy((void*)(rxp[aid]+(timestamp[packet_id]-timestamp[0])), + (void*)temp_rx, + spp_eth<<2); clock_gettime( CLOCK_MONOTONIC, &end_decomp); LOG_D(HW,"[SF %d] IF_Read_Time: %"PRId64"\n",subframe,clock_difftime_ns(start_decomp, end_decomp)); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); - for (i=0; i < fp->nb_antennas_rx; i++) - rxp[i] += spp_eth; + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_IF0, 0 ); } } *proc_timestamp = timestamp[0]; - - } else if (packet_type == IF5_MOBIPASS) { - if (ru->if_timing == synch_to_mobipass_standalone) { - uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; - openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength]; - int32_t *rx_buffer=NULL; - __m128i *data_block=NULL, *data_block_head=NULL; - __m128i *rxp128; - __m128i r0; - - unsigned char _rx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)]; - rx_buffer = (int32_t *)_rx_buffer; - data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t); - - rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms->samples_per_tti]; - rxp128 = (__m128i *) (rxp[0]); - - packet_id=0; - while(packet_idsamples_per_tti/db_fulllength) { - data_block = data_block_head; - - ru->ifdevice.trx_read_func(&ru->ifdevice, - ×tamp_mobipass[packet_id], - (void**)&rx_buffer, - db_fulllength, - 1 - ); - - //store rxdata and increase packet_id - rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms->samples_per_tti)+packet_id*db_fulllength]; - rxp128 = (__m128i *) (rxp[0]); - for (i=0; i>2; i+=2) { - r0 = _mm_loadu_si128(data_block++); - *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4); - *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4); - } - packet_id++; - }//end while - - *proc_timestamp = ntohl(timestamp_mobipass[0]); - } else { - - uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES; - openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength]; -#ifdef DEBUG_UL_MOBIPASS - int lower_offset = 0; - int upper_offset = 70000; -#endif - int subframe_skip = 0; - int reset_flag = 0; - int32_t *rx_buffer=NULL; - __m128i *data_block=NULL, *data_block_head=NULL; - __m128i *rxp128; - __m128i r0; - - //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); - rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)); - IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES); - data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t); - - rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms->samples_per_tti]; - rxp128 = (__m128i *) (rxp[0]); - - RU_proc_t *proc = &ru->proc; -/* - // while(packet_idsamples_per_tti/db_fulllength) { - data_block = data_block_head; - - eNB->ifdevice.trx_read_func(&eNB->ifdevice, - &ts0, - (void**)&rx_buffer, - db_fulllength, - 1 - ); - - if ((header->seqno == 1)&&(first_packet==1)) { - first_packet = 0; //ignore the packets before synchnorization - packet_id = 0; - ts_offset = ntohl(ts0); - } - if (first_packet==0) { - packet_cnt++; - ts = ntohl(ts0); - packet_id = (ts-ts_offset)/db_fulllength; - packet_id = packet_id % (fp->samples_per_tti/db_fulllength); - - printf("[IF5_tools]packet_id:%d\n", packet_id); - // if (ts_stored == 0) { - // ts_stored = 1; - *proc_timestamp = ntohl(ts - (packet_id*db_fulllength)); - // } - rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength]; - rxp128 = (__m128i *) (rxp[0]); - - for (i=0; i>2; i+=2) { - r0 = _mm_loadu_si128(data_block++); - *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4); - *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4); - } - } - // }//end while -*/ - - - packet_id=0; - while(packet_idsamples_per_tti/db_fulllength) { - data_block = data_block_head; - - - ru->ifdevice.trx_read_func(&ru->ifdevice, - ×tamp_mobipass[packet_id], - (void**)&rx_buffer, - db_fulllength, - 1 - ); -#ifdef DEBUG_UL_MOBIPASS - if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) { - //ignore the packet - subframe_skip_extra = (subframe_skip_extra + 1)%67; - LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno); - } -#endif - //skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets - if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){ - subframe_skip++; - offset_cnt = header->seqno; - } else { - if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){ -#ifdef DEBUG_UL_MOBIPASS - LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id); -#endif - reset_flag=1; - } - if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) { - packet_id = 1; - reset_flag = 0; - } - start_flag = 0; - - //store rxdata and increase packet_id - rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms->samples_per_tti)+packet_id*db_fulllength]; - rxp128 = (__m128i *) (rxp[0]); - for (i=0; i>2; i+=2) { - r0 = _mm_loadu_si128(data_block++); - *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4); - *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4); - } - packet_id++; - offset_cnt = (header->seqno+1)&255; - } - }//end while - - *proc_timestamp = ntohl(timestamp_mobipass[0]); -#ifdef DEBUG_UL_MOBIPASS - LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ", *proc_timestamp); - if (eNB->CC_id>0) { - rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti)); - if (rxe > 0){ - LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe); - - // LOG_M("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5); - // exit(-1); - } - } -#endif - free(rx_buffer); - - - } } else { AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type); } diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index 6d8b58818b..1725588f4c 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -716,6 +716,7 @@ void generate_phich_top(PHY_VARS_eNB *eNB, uint8_t NSF_PHICH = 4; uint8_t pusch_subframe=-1; uint8_t i; + uint8_t harq_pid = 0; int subframe = proc->subframe_tx; phich_config_t *phich; @@ -748,16 +749,20 @@ void generate_phich_top(PHY_VARS_eNB *eNB, nseq_PHICH = ((phich->first_rb/Ngroup_PHICH) + phich->n_DMRS)%(2*NSF_PHICH); + harq_pid = subframe2harq_pid(frame_parms,phich_frame2_pusch_frame(frame_parms,proc->frame_tx,subframe),pusch_subframe); + if (harq_pid == 255) { + LOG_E(PHY,"FATAL ERROR: illegal harq_pid, returning\n"); + return; + } LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Generating PHICH, AMP %d ngroup_PHICH %d/%d, nseq_PHICH %d : HI %d, first_rb %d)\n", - eNB->Mod_id,subframe2harq_pid(frame_parms, - phich_frame2_pusch_frame(frame_parms,proc->frame_tx,subframe),pusch_subframe),proc->frame_tx, + eNB->Mod_id,harq_pid,proc->frame_tx, subframe,amp,ngroup_PHICH,Ngroup_PHICH,nseq_PHICH, phich->hi, phich->first_rb); T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe), T_INT(-1 /* TODO: rnti */), - T_INT(subframe2harq_pid(frame_parms,phich_frame2_pusch_frame(frame_parms,proc->frame_tx,subframe),pusch_subframe)), + T_INT(harq_pid), T_INT(Ngroup_PHICH), T_INT(NSF_PHICH), T_INT(ngroup_PHICH), T_INT(nseq_PHICH), T_INT(phich->hi), diff --git a/openair1/PHY/LTE_TRANSPORT/phich_common.c b/openair1/PHY/LTE_TRANSPORT/phich_common.c index 89c826be66..302229b88d 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich_common.c +++ b/openair1/PHY/LTE_TRANSPORT/phich_common.c @@ -102,6 +102,34 @@ unsigned char subframe2_ul_harq(LTE_DL_FRAME_PARMS *frame_parms,unsigned char su return(subframe&7); switch (frame_parms->tdd_config) { + case 1: + if (subframe == 6) { + return(0); + } else if (subframe==9){ + return(1); + } else if (subframe==1){ + return(2); + } else if (subframe==4){ + return(3); + } else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; + case 2: + if (subframe == 3) { + return(1); + } else if (subframe==8){ + return(0); + } else { + LOG_E(PHY,"phich.c: subframe2_ul_harq, illegal subframe %d for tdd_config %d\n", + subframe,frame_parms->tdd_config); + return(0); + } + + break; case 3: if ( (subframe == 8) || (subframe == 9) ) { return(subframe-8); diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 24faf584d3..9e0fa239f6 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -89,7 +89,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, int32_t *prach_ifft=(int32_t *)NULL; int32_t **prach_ifftp=(int32_t **)NULL; int prach_ifft_cnt=0; - + int exit_flag=0; LTE_DL_FRAME_PARMS *fp; int nb_rx; if(eNB) { @@ -167,7 +167,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex); } } else { - rxsigF = ru->prach_rxsigF; + rxsigF = ru->prach_rxsigF[0]; if (LOG_DEBUGFLAG(PRACH)) { if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n", @@ -177,32 +177,33 @@ void rx_prach0(PHY_VARS_eNB *eNB, } AssertFatal(ru!=NULL,"ru is null\n"); - + int8_t dBEn0=0; for (aa=0; aaif_south == LOCAL_RF) { // set the time-domain signal if we have to use it in this node + if (ru->if_south == LOCAL_RF || ru->function == NGFI_RAU_IF5) { // set the time-domain signal if we have to use it in this node // DJP - indexing below in subframe zero takes us off the beginning of the array??? prach[aa] = (int16_t *)&ru->common.rxdata[aa][(subframe*fp->samples_per_tti)-ru->N_TA_offset]; if (LOG_DUMPFLAG(PRACH)) { int32_t en0=signal_energy((int32_t *)prach[aa],fp->samples_per_tti); - int8_t dbEn0 = dB_fixed(en0); - int8_t rach_dBm = dbEn0 - ru->rx_total_gain_dB; + dBEn0 = dB_fixed(en0); + int8_t rach_dBm = dBEn0 - ru->rx_total_gain_dB; char buffer[80]; - if (dbEn0>32 && prach[0]!= NULL) { + if (dBEn0>30 && prach[0]!= NULL) { static int counter=0; - sprintf(buffer, "%s%d", "/tmp/prach_rx",counter); - LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,13); + sprintf(buffer, "%s%d", "/tmp/prach_rx.m",counter); + LOG_M(buffer,"prach_rx",prach[0],fp->samples_per_tti,1,1); + exit_flag=1; } - if (dB_fixed(en0)>32) { + if (dBEn0>30) { sprintf(buffer, "rach_dBm:%d",rach_dBm); - if (prach[0]!= NULL) LOG_M("prach_rx","prach_rx",prach[0],fp->samples_per_tti,1,1); + if (prach[0]!= NULL) LOG_M("prach_rx.m","prach_rx",prach[0],fp->samples_per_tti,1,1); LOG_I(PHY,"RU %d, br_flag %d ce_level %d frame %d subframe %d per_tti:%d prach:%p (energy %d) TA:%d %s rxdata:%p index:%d\n", ru->idx,br_flag,ce_level,frame_prach,subframe,fp->samples_per_tti, - prach[aa],dbEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa], + prach[aa],dBEn0,ru->N_TA_offset,buffer,ru->common.rxdata[aa], (subframe*fp->samples_per_tti)-ru->N_TA_offset); } } @@ -415,7 +416,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, if ( LOG_DEBUGFLAG(PRACH)) { int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); - if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en); + if ((en > 10)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,frame_prach,subframe,en); } } @@ -454,9 +455,9 @@ void rx_prach0(PHY_VARS_eNB *eNB, for (preamble_index=0 ; preamble_index<64 ; preamble_index++) { if (LOG_DEBUGFLAG(PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); + // int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); - if (en>60) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag); + if (dBEn0>30) LOG_I(PHY,"frame %d, subframe %d : Trying preamble %d (br_flag %d)\n",frame_prach,subframe,preamble_index,br_flag); } if (restricted_set == 0) { @@ -539,10 +540,10 @@ void rx_prach0(PHY_VARS_eNB *eNB, // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); + //en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); - if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n", - frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,en); + if (dBEn0>30) LOG_I(PHY,"frame %d, subframe %d : preamble index %d: offset %d, preamble shift %d (br_flag %d, en %d)\n", + frame_prach,subframe,preamble_index,preamble_offset,preamble_shift,br_flag,dBEn0); } log2_ifft_size = 10; @@ -564,13 +565,13 @@ void rx_prach0(PHY_VARS_eNB *eNB, memset(prachF, 0, sizeof(int16_t)*2*1024 ); - if (LOG_DUMPFLAG(PRACH)) { + if (LOG_DUMPFLAG(PRACH)) { if (prach[0]!= NULL) LOG_M("prach_rx0.m","prach_rx0",prach[0],6144+792,1,1); LOG_M("prach_rx1.m","prach_rx1",prach[1],6144+792,1,1); LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],12288,1,1); LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],12288,1,1); - } + } for (aa=0; aa*max_preamble_energy) { *max_preamble_energy = levdB; @@ -633,9 +634,9 @@ void rx_prach0(PHY_VARS_eNB *eNB, *max_preamble = preamble_index; if (LOG_DEBUGFLAG(PRACH)) { - int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); + // int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); - if ((en>60) && (br_flag==1)) + if (dBEn0>30) LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n", frame_prach,subframe, *max_preamble_energy,*max_preamble_delay, @@ -648,10 +649,10 @@ void rx_prach0(PHY_VARS_eNB *eNB, *avg_preamble_energy=dB_fixed(avg_en/64); - if (LOG_DUMPFLAG(PRACH)) { + if (exit_flag==1) { int en = dB_fixed(signal_energy((int32_t *)&rxsigF[0][0],840)); - if (en>60) { + if (en>30) { k = (12*n_ra_prb) - 6*fp->N_RB_UL; if (k<0) k+=fp->ofdm_symbol_size; @@ -665,19 +666,20 @@ void rx_prach0(PHY_VARS_eNB *eNB, LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); LOG_M("Xu.m","xu",Xu,N_ZC,1,1); LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); - exit(-1); + LOG_M("SF2_3.m","sf2_3",&ru->common.rxdata[0][2*fp->samples_per_tti],2*fp->samples_per_tti,1,1); } else { LOG_E(PHY,"Dumping prach (br_flag %d), k = %d (n_ra_prb %d)\n",br_flag,k,n_ra_prb); LOG_M("rxsigF_br.m","prach_rxF_br",&rxsigF[0][0],12288,1,1); LOG_M("prach_rxF_comp0_br.m","prach_rxF_comp0_br",prachF,1024,1,1); LOG_M("Xu_br.m","xu_br",Xu,N_ZC,1,1); LOG_M("prach_ifft0_br.m","prach_t0_br",prach_ifft,1024,1,1); - exit(-1); } } } /* LOG_DUMPFLAG(PRACH) */ if (eNB) stop_meas(&eNB->rx_prach); + AssertFatal(exit_flag==0,"exiting\n"); + } diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index 8637e80137..c72fa1b480 100644 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -721,6 +721,137 @@ int16_t pucchfmt3_Decode( int16_t b[48], } } + +uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB, + int frame, + uint8_t subframe, + uint8_t shortened_format +) +//----------------------------------------------------------------------------- +{ + LTE_eNB_COMMON *common_vars = &eNB->common_vars; + LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; + + uint32_t u,v,n,aa; + uint32_t z[12*14]; + int16_t *zptr; + int16_t rxcomp[NB_ANTENNAS_RX][2*12*14]; + uint8_t ns,N_UL_symb,nsymb,n_cs_base; + uint16_t i,j,re_offset; + uint8_t m,l; + uint8_t n_cs,alpha_ind; + int16_t tmp_re,tmp_im,W_re=0,W_im=0; + int16_t W4_nouse[4]={32767,32767,-32768,-32768}; + int32_t n0_IQ[2]; + double interference_power; + int16_t *rxptr; + uint32_t symbol_offset; + + uint32_t u0 = (frame_parms->pucch_config_common.grouphop[subframe<<1]) % 30; + uint32_t u1 = (frame_parms->pucch_config_common.grouphop[1+(subframe<<1)]) % 30; + uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; + uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; + int calc_cnt; + + zptr = (int16_t *)z; + N_UL_symb = (frame_parms->Ncp==NORMAL) ? 7 : 6; + + interference_power=0.0; + calc_cnt=0; + // loop over 2 slots + for (n_cs_base=0; n_cs_base<12; n_cs_base++) { + zptr = (int16_t *)z; + for (ns=(subframe<<1),u=u0,v=v0; ns<(2+(subframe<<1)); ns++,u=u1,v=v1) { + + //loop over symbols in slot + for (l=0; lncs_cell[ns][l]+n_cs_base; + if(((l>1)&&(l=N_UL_symb-2)) { // data + W_re=W4_nouse[l-N_UL_symb+4]; + W_im=0; + } + + alpha_ind=0; + // compute output sequence + + for (n=0; n<12; n++) { + + // this is r_uv^alpha(n) + tmp_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15); + tmp_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15); + + // this is S(ns)*w_noc(m)*r_uv^alpha(n) + zptr[n<<1] = (tmp_re*W_re - tmp_im*W_im)>>15; + zptr[1+(n<<1)] = -(tmp_re*W_im + tmp_im*W_re)>>15; + + alpha_ind = (alpha_ind + n_cs)%12; + } // n + + zptr+=24; + } // l + } // ns + + m = 1; + + nsymb = N_UL_symb<<1; + + zptr = (int16_t*)z; + + // Do detection + for (aa=0; aanb_antennas_rx; aa++) { + n0_IQ[0]=0; + n0_IQ[1]=0; + for (j=0,l=0; l1)&&((l%N_UL_symb)=N_UL_symb) && (shortened_format==1)) ){ + j+=24; + continue; + } + if ((l<(nsymb>>1)) && ((m&1) == 0)) + re_offset = (m*6) + frame_parms->first_carrier_offset; + else if ((l<(nsymb>>1)) && ((m&1) == 1)) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else if ((m&1) == 0) + re_offset = frame_parms->first_carrier_offset + (frame_parms->N_RB_DL - (m>>1) - 1)*12; + else + re_offset = ((m-1)*6) + frame_parms->first_carrier_offset; + + if (re_offset > frame_parms->ofdm_symbol_size) + re_offset -= (frame_parms->ofdm_symbol_size); + + symbol_offset = (unsigned int)frame_parms->ofdm_symbol_size*l; + rxptr = (int16_t *)&common_vars->rxdataF[aa][symbol_offset]; + + for (i=0; i<12; i++,j+=2,re_offset++) { + if (re_offset==frame_parms->ofdm_symbol_size) + re_offset = 0; + + rxcomp[aa][j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15) - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15); + rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15); + n0_IQ[0]+=rxcomp[aa][j]; + n0_IQ[1]+=rxcomp[aa][1+j]; + } //re + calc_cnt++; + } // symbol + n0_IQ[0]/=12; + n0_IQ[1]/=12; + interference_power+= (double)(n0_IQ[0]*n0_IQ[0]+n0_IQ[1]*n0_IQ[1]); + } // antenna + } + interference_power /= calc_cnt; + eNB->measurements.n0_pucch_dB = dB_fixed_x10((int)interference_power)/10; + LOG_D(PHY,"estimate pucch noise %lf %d %d\n",interference_power,calc_cnt,eNB->measurements.n0_pucch_dB); + return 0; +} + + /* PUCCH format3 << */ uint32_t rx_pucch(PHY_VARS_eNB *eNB, @@ -740,7 +871,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, static int first_call = 1; LTE_eNB_COMMON *common_vars = &eNB->common_vars; LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; - int8_t sigma2_dB = max(eNB->measurements.n0_subband_power_tot_dB[0], eNB->measurements.n0_subband_power_tot_dB[eNB->frame_parms.N_RB_UL-1]); + int8_t sigma2_dB = eNB->measurements.n0_pucch_dB; + uint32_t u,v,n,aa; uint32_t z[12*14]; int16_t *zptr; @@ -765,8 +897,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, uint8_t deltaPUCCH_Shift = frame_parms->pucch_config_common.deltaPUCCH_Shift; uint8_t NRB2 = frame_parms->pucch_config_common.nRB_CQI; uint8_t Ncs1_div_deltaPUCCH_Shift = frame_parms->pucch_config_common.nCS_AN; - uint32_t u0 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[subframe<<1]) % 30; - uint32_t u1 = (frame_parms->Nid_cell + frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.grouphop[1+(subframe<<1)]) % 30; + + uint32_t u0 = (frame_parms->pucch_config_common.grouphop[subframe<<1]) % 30; + uint32_t u1 = (frame_parms->pucch_config_common.grouphop[1+(subframe<<1)]) % 30; uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1]; uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)]; int chL; @@ -1141,8 +1274,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, } // this is total energy received, summed over data and reference - stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) + - ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + if (fmt==pucch_format1a){ + stat += ((((stat_re*stat_re)) + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + }else{ + stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) + + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + } + // now second slot stat_re=0; stat_im=0; @@ -1170,8 +1308,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, #ifdef DEBUG_PUCCH_RX printf("aa%d re %d : phase %d : stat %d\n",aa,re,phase,stat); #endif - stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) + - ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + if (fmt==pucch_format1a){ + stat += ((((stat_re*stat_re)) + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + }else{ + stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) + + ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb); + } + } //re } // aa diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 4ce113f78e..9e37821b05 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -621,7 +621,11 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, uint16_t frame, uint8_t Ns); - +uint32_t calc_pucch_1x_interference(PHY_VARS_eNB *eNB, + int frame, + uint8_t subframe, + uint8_t shortened_format +); uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB, PUCCH_FMT_t fmt, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 1b23fc99bf..eeab616097 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -755,6 +755,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, __m128i *ul_ch128,*ul_ch_mag128,*ul_ch_mag128b,*rxdataF128,*rxdataF_comp128; uint8_t aarx;//,symbol_mod; __m128i mmtmpU0,mmtmpU1,mmtmpU2,mmtmpU3; + #elif defined(__arm__) int16x4_t *ul_ch128,*rxdataF128; int16x8_t *ul_ch_mag128,*ul_ch_mag128b,*rxdataF_comp128; @@ -762,6 +763,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, int32x4_t mmtmpU0,mmtmpU1,mmtmpU0b,mmtmpU1b; int16_t conj[4]__attribute__((aligned(16))) = {1,-1,1,-1}; int32x4_t output_shift128 = vmovq_n_s32(-(int32_t)output_shift); + #endif for (aarx=0; aarxnb_antennas_rx; aarx++) { @@ -872,6 +874,7 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, rxdataF_comp128[0] = _mm_add_epi16(rxdataF_comp128[0],(*(__m128i *)&jitter[0])); rxdataF_comp128[1] = _mm_add_epi16(rxdataF_comp128[1],(*(__m128i *)&jitter[0])); rxdataF_comp128[2] = _mm_add_epi16(rxdataF_comp128[2],(*(__m128i *)&jitter[0])); + ul_ch128+=3; ul_ch_mag128+=3; ul_ch_mag128b+=3; @@ -918,9 +921,10 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext, mmtmpU1 = vqshlq_s32(mmtmpU1,-output_shift128); rxdataF_comp128[2] = vcombine_s16(vmovn_s32(mmtmpU0),vmovn_s32(mmtmpU1)); // Add a jitter to compensate for the saturation in "packs" resulting in a bias on the DC after IDFT - rxdataF_comp128[0] = vqaddq_s16(rxdataF_comp128[0],(*(int16x8_t *)&jitter[0])); - rxdataF_comp128[1] = vqaddq_s16(rxdataF_comp128[1],(*(int16x8_t *)&jitter[0])); - rxdataF_comp128[2] = vqaddq_s16(rxdataF_comp128[2],(*(int16x8_t *)&jitter[0])); + rxdataF_comp128[0] = vqaddq_s16(rxdataF_comp128[0],(*(int16x8_t*)&jitter[0])); + rxdataF_comp128[1] = vqaddq_s16(rxdataF_comp128[1],(*(int16x8_t*)&jitter[0])); + rxdataF_comp128[2] = vqaddq_s16(rxdataF_comp128[2],(*(int16x8_t*)&jitter[0])); + ul_ch128+=6; ul_ch_mag128+=3; ul_ch_mag128b+=3; @@ -1031,6 +1035,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, AssertFatal(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb > 0, "PUSCH (%d/%x) nb_rb=0!\n", harq_pid,ulsch[UE_id]->rnti); + for (l=0; l<(frame_parms->symbols_per_tti-ulsch[UE_id]->harq_processes[harq_pid]->srs_active); l++) { if(LOG_DEBUGFLAG(DEBUG_ULSCH)) { LOG_I(PHY,"rx_ulsch : symbol %d (first_rb %d,nb_rb %d), rxdataF %p, rxdataF_ext %p\n",l, @@ -1064,18 +1069,38 @@ void rx_ulsch(PHY_VARS_eNB *eNB, if (deltaMCS==1) { // Note we're using TBS instead of sumKr, since didn't run segmentation yet! MPR_times_100Ks = 500*ulsch[UE_id]->harq_processes[harq_pid]->TBS/(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*4*ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); - AssertFatal(MPR_times_100Ks < 750 && MPR_times_100Ks >= 0,"Impossible value for MPR_times_100Ks %d (TBS %d,Nre %d)\n", - MPR_times_100Ks,ulsch[UE_id]->harq_processes[harq_pid]->TBS, - (ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*4*ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch)); - if (MPR_times_100Ks > 0) correction_factor = ulsch_power_LUT[MPR_times_100Ks]; + if ((MPR_times_100Ks > 0)&&(MPR_times_100Ks < 750)){ + correction_factor = ulsch_power_LUT[MPR_times_100Ks]; + }else{ + correction_factor = 1; + } } for (i=0; inb_antennas_rx; i++) { - pusch_vars->ulsch_power[i] = signal_energy_nodc(pusch_vars->drs_ch_estimates[i], - ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12)/correction_factor; - LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, - ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_times10(pusch_vars->ulsch_power[i])); + //symbol 3 + int symbol_offset = frame_parms->N_RB_UL*12*(3 - frame_parms->Ncp); + pusch_vars->ulsch_interference_power[i] = interference_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12); + pusch_vars->ulsch_power[i] = signal_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12); + //symbol 3+7 + symbol_offset = frame_parms->N_RB_UL*12*((3 - frame_parms->Ncp)+(7-frame_parms->Ncp)); + pusch_vars->ulsch_interference_power[i] += interference_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12); + pusch_vars->ulsch_power[i] += signal_power(&pusch_vars->drs_ch_estimates[i][symbol_offset],ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12); + + pusch_vars->ulsch_interference_power[i] = pusch_vars->ulsch_interference_power[i]/correction_factor; + pusch_vars->ulsch_power[i] = pusch_vars->ulsch_power[i]/correction_factor; + + if(pusch_vars->ulsch_power[i]>0x20000000){ + pusch_vars->ulsch_power[i] = 0x20000000; + pusch_vars->ulsch_interference_power[i] = 1; + }else{ + pusch_vars->ulsch_power[i] -= pusch_vars->ulsch_interference_power[i]; + if(pusch_vars->ulsch_power[i]<1) pusch_vars->ulsch_power[i] = 1; + if(pusch_vars->ulsch_interference_power[i]<1)pusch_vars->ulsch_interference_power[i] = 1; + } + + LOG_D(PHY,"%4.4d.%d power harq_pid %d rb %2.2d TBS %2.2d (MPR_times_Ks %d correction %d) power %d dBtimes10\n", proc->frame_rx, proc->subframe_rx, harq_pid, ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, ulsch[UE_id]->harq_processes[harq_pid]->TBS,MPR_times_100Ks,correction_factor,dB_fixed_x10(pusch_vars->ulsch_power[i])); + } ulsch_channel_level(pusch_vars->drs_ch_estimates, diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 228299095f..72a1334fe9 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -49,12 +49,14 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int reset_freq_est); int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue, - unsigned char l, - unsigned char Ns, - int sample_offset, - int no_prefix); + UE_nr_rxtx_proc_t *proc, + unsigned char l, + unsigned char Ns, + int sample_offset, + int no_prefix); int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, int sample_offset, diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 652421f77c..0a7088ba39 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -506,10 +506,10 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq) { const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10; const double Tc=(1/480e3/4096); - const double Nu=2048*64*.5; + const double Nu=2048*64*(1/(float)(1<numerology_index)); const double f0= (double)CarrierFreq; - const double Ncp0=16*64 + (144*64*.5); - const double Ncp1=(144*64*.5); + const double Ncp0=16*64 + (144*64*(1/(float)(1<numerology_index))); + const double Ncp1=(144*64*(1/(float)(1<numerology_index))); double tl=0,poff,exp_re,exp_im; double Ncp,Ncpm1=Ncp0; diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 31d8754768..3d2be905ac 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -112,4 +112,10 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq); +void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, + int32_t *rxdataF, + int slot, + int first_symbol, + int nsymb, + int length); #endif diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 92aea419af..2d86b46742 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -90,9 +90,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input if(nb_symbols == 0) return; - short temp[2*2*6144*4] __attribute__((aligned(32))); - unsigned short i,j; - short k; + int16_t temp[2*2*6144*4] __attribute__((aligned(32))); + int i,j; volatile int *output_ptr=(int*)0; @@ -190,18 +189,9 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input if (fftsize==128) #endif { - /*for (j=0; j=-nb_prefix_samples; k--) { - output_ptr[k] = output_ptr[--j]; - } - + memcpy((void*)&output_ptr[-nb_prefix_samples],(void*)&output_ptr[fftsize-nb_prefix_samples],nb_prefix_samples<<2); break; case CYCLIC_SUFFIX: diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 2ffdb013a5..60b28d4ad1 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -37,6 +37,7 @@ #endif*/ int nr_slot_fep(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, int sample_offset, @@ -125,7 +126,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } for (aa=0; aanb_antennas_rx; aa++) { - memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); + memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); rx_offset = sample_offset + slot_offset - SOFFSET; // Align with 256 bit @@ -157,14 +158,14 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][rx_offset % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); #endif dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif @@ -185,11 +186,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly dft(dftsize,(int16_t *) &common_vars->rxdata[aa][(rx_offset) % frame_length_samples], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); @@ -206,9 +207,9 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); @@ -222,6 +223,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, unsigned char symbol, unsigned char Ns, int sample_offset, @@ -310,7 +312,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, } for (aa=0; aanb_antennas_rx; aa++) { - memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); + memset(&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int)); rx_offset = sample_offset + slot_offset - SOFFSET; // Align with 256 bit @@ -342,7 +344,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly #if UE_TIMING_TRACE start_meas(&ue->rx_dft_stats); @@ -350,7 +352,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); #endif @@ -371,10 +373,10 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, (void *) &common_vars->rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size*sizeof(int)); dft(dftsize,(int16_t *)tmp_dft_in, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } else { // use dft input from RX buffer directly dft(dftsize,(int16_t *) &common_vars->rxdata[aa][rx_offset], - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1); } #if UE_TIMING_TRACE stop_meas(&ue->rx_dft_stats); @@ -393,9 +395,9 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); #endif - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); @@ -483,21 +485,41 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, dft(dftsize,(int16_t *)&tmp_dft_in, (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); } - else - dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset], + else { + //dft(dftsize,(int16_t *)&rxdata[rxdata_offset-sample_offset], + // (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); + memcpy((void *)tmp_dft_in, + (void *) &rxdata[rxdata_offset-sample_offset], + (frame_parms->ofdm_symbol_size)*sizeof(int)); + dft(dftsize,(int16_t *)&tmp_dft_in, (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); + } // clear DC carrier from OFDM symbols rxdataF[symbol * frame_parms->ofdm_symbol_size] = 0; - int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",Ns,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); - rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], - frame_parms->ofdm_symbol_size, - 15); return(0); } + +void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, + int32_t *rxdataF, + int slot, + int first_symbol, + int nsymb, + int length) { + + + int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; + + for (int symbol=0;symbolsymbol_rotation)[symbol+symb_offset]; + ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], + (int16_t*)&rot2, + (int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol], + length, + 15); + } +} diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index b6388fb903..713e71674b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -25,10 +25,14 @@ #include "nr_ul_estimation.h" #include "PHY/sse_intrin.h" #include "PHY/NR_REFSIG/nr_refsig.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" +#include "PHY/NR_REFSIG/ul_ref_seq_nr.h" + + //#define DEBUG_CH //#define DEBUG_PUSCH @@ -118,15 +122,36 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, break; } - //------------------generate DMRS------------------// - if (pusch_pdu->transform_precoding==1) // if transform precoding is disabled + if (pusch_pdu->transform_precoding == transform_precoder_disabled) nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); - else - nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + + else { // if transform precoding or SC-FDMA is enabled in Uplink + // NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible + uint16_t index = get_index_for_dmrs_lowpapr_seq(nb_rb_pusch * (NR_NB_SC_PER_RB/2)); + uint8_t u = pusch_pdu->dfts_ofdm.low_papr_group_number; + uint8_t v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; + int16_t *dmrs_seq = gNB_dmrs_lowpaprtype1_sequence[u][v][index]; + + AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); + + LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); + + nr_pusch_lowpaprtype1_dmrs_rx(gNB, Ns, dmrs_seq, &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + + #ifdef DEBUG_PUSCH + printf ("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); + LOG_M("gNb_DMRS_SEQ.m","gNb_DMRS_SEQ", dmrs_seq,6*nb_rb_pusch,1,1); + #endif + + } //------------------------------------------------// + + + #ifdef DEBUG_PUSCH for (int i=0;i<(6*nb_rb_pusch);i++) printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]); @@ -533,384 +558,107 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, * 3) Compensated DMRS based estimated signal with PTRS estimation for slot *********************************************************************/ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, + NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t *rel15_ul, uint8_t ulsch_id, uint8_t nr_tti_rx, - uint8_t dmrs_symbol_flag, unsigned char symbol, uint32_t nb_re_pusch) { - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - int16_t *phase_per_symbol; - - uint8_t L_ptrs = 0; - uint8_t right_side_ref = 0; - uint8_t left_side_ref = 0; - uint8_t nb_dmrs_in_slot = 0; - //#define DEBUG_UL_PTRS 1 - /* First symbol calculate PTRS symbol index for slot & set the variables */ - if(symbol == rel15_ul->start_symbol_index) - { - gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0; - L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density); - set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols, - rel15_ul->nr_of_symbols, - rel15_ul->start_symbol_index, - L_ptrs, - rel15_ul->ul_dmrs_symb_pos); - }/* First symbol check */ + int16_t *phase_per_symbol = NULL; + int32_t *ptrs_re_symbol = NULL; + int8_t ret = 0; + uint8_t symbInSlot = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols; + uint8_t *startSymbIndex = &rel15_ul->start_symbol_index; + uint8_t *nbSymb = &rel15_ul->nr_of_symbols; + uint8_t *L_ptrs = &rel15_ul->pusch_ptrs.ptrs_time_density; + uint8_t *K_ptrs = &rel15_ul->pusch_ptrs.ptrs_freq_density; + uint16_t *dmrsSymbPos = &rel15_ul->ul_dmrs_symb_pos; + uint16_t *ptrsSymbPos = &gNB->pusch_vars[ulsch_id]->ptrs_symbols; + uint8_t *ptrsSymbIdx = &gNB->pusch_vars[ulsch_id]->ptrs_symbol_index; + uint8_t *dmrsConfigType = &rel15_ul->dmrs_config_type; + uint16_t *nb_rb = &rel15_ul->rb_size; + uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset; /* loop over antennas */ - for (int aarx=0; aarx< frame_parms->nb_antennas_rx; aarx++) - { + for (int aarx=0; aarxnb_antennas_rx; aarx++) { phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx]; - /* set the previous estimations to zero at first symbol */ - if(symbol == rel15_ul->start_symbol_index) - { - memset(phase_per_symbol,0,sizeof(int32_t)*frame_parms->symbols_per_slot); + ptrs_re_symbol = &gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot; + *ptrs_re_symbol = 0; + phase_per_symbol[(2*symbol)+1] = 0; // Imag + /* set DMRS estimates to 0 angle with magnitude 1 */ + if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { + /* set DMRS real estimation to 32767 */ + phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767 +#ifdef DEBUG_UL_PTRS + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]); +#endif + } + else {// real ptrs value is set to 0 + phase_per_symbol[2*symbol] = 0; // Real + } + + if(symbol == *startSymbIndex) { + *ptrsSymbPos = 0; + set_ptrs_symb_idx(ptrsSymbPos, + *nbSymb, + *startSymbIndex, + 1<< *L_ptrs, + *dmrsSymbPos); } /* if not PTRS symbol set current ptrs symbol index to zero*/ - gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = 0; - gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0; + *ptrsSymbIdx = 0; /* Check if current symbol contains PTRS */ - if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols)) - { - gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol; + if(is_ptrs_symbol(symbol, *ptrsSymbPos)) { + *ptrsSymbIdx = symbol; /*------------------------------------------------------------------------------------------------------- */ - /* 1) Estimate phase noise per PTRS symbol */ + /* 1) Estimate common phase error per PTRS symbol */ /*------------------------------------------------------------------------------------------------------- */ - nr_pusch_phase_estimation(frame_parms, - rel15_ul, - (int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch], - nr_tti_rx, - symbol, - (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)], - gNB->nr_gold_pusch_dmrs[rel15_ul->scid], - &phase_per_symbol[2* symbol], - &gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol); - } - /* DMRS Symbol channel estimates extraction */ - else if(dmrs_symbol_flag) - { - phase_per_symbol[2* symbol]= (int16_t)((1<<15)-1); // 32767 - phase_per_symbol[2* symbol +1]= 0;// no angle + nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb, + rel15_ul->rnti, + (int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch], + nr_tti_rx, + symbol,frame_parms->ofdm_symbol_size, + (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)], + gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol], + &phase_per_symbol[2* symbol], + ptrs_re_symbol); } /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/ - if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1)) - { - nb_dmrs_in_slot = get_dmrs_symbols_in_slot(rel15_ul->ul_dmrs_symb_pos,(rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols)); - for(uint8_t dmrs_sym = 0; dmrs_sym < nb_dmrs_in_slot; dmrs_sym ++) - { - if(dmrs_sym == 0) - { - /* get first DMRS position */ - left_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols)); - /* get first DMRS position is not at start symbol position then we need to extrapolate left side */ - if(left_side_ref > rel15_ul->start_symbol_index) - { - left_side_ref = rel15_ul->start_symbol_index; - } + if(symbol == (symbInSlot -1)) { + /*------------------------------------------------------------------------------------------------------- */ + /* 2) Interpolate PTRS estimated value in TD */ + /*------------------------------------------------------------------------------------------------------- */ + /* If L-PTRS is > 0 then we need interpolation */ + if(*L_ptrs > 0) { + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb); + if(ret != 0) { + LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); } - /* get the next symbol from left_side_ref value */ - right_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, left_side_ref+1, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols)); - /* if no symbol found then interpolate till end of slot*/ - if(right_side_ref == 0) - { - right_side_ref = (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); - } - /*------------------------------------------------------------------------------------------------------- */ - /* 2) Interpolate PTRS estimated value in TD */ - /*------------------------------------------------------------------------------------------------------- */ - nr_pusch_phase_interpolation(phase_per_symbol,left_side_ref,right_side_ref); - /* set left to last dmrs */ - left_side_ref = right_side_ref; - } /*loop over dmrs positions */ - + } #ifdef DEBUG_UL_PTRS - LOG_M("ptrsEst.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); - LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp", + LOG_M("ptrsEstUl.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); + LOG_M("rxdataF_bf_ptrs_comp_ul.m","bf_ptrs_cmp", &gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size], rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1); #endif - /*------------------------------------------------------------------------------------------------------- */ /* 3) Compensated DMRS based estimated signal with PTRS estimation */ /*--------------------------------------------------------------------------------------------------------*/ - for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) - { + for(uint8_t i = *startSymbIndex; i< symbInSlot ;i++) { + /* DMRS Symbol has 0 phase so no need to rotate the respective symbol */ + /* Skip rotation if the slot processing is wrong */ + if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_UL_PTRS - printf("PTRS: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); + printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); #endif - rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], - &phase_per_symbol[2* i], - (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], - (rel15_ul->rb_size * NR_NB_SC_PER_RB), - 15); + rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], + &phase_per_symbol[2* i], + (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], + ((*nb_rb) * NR_NB_SC_PER_RB), 15); + }// if not DMRS Symbol }// symbol loop - }//interpolation and compensation - }// Antenna loop -} - -/******************************************************************* - * - * NAME : nr_pusch_phase_estimation - * - * PARAMETERS : frame_parms : UL frame parameters - * rel15_ul : UL PDU Structure - * Ns : - * Symbol : OFDM symbol index - * rxF : Channel compensated signal - * ptrs_gold_seq: Gold sequence for PTRS regeneration - * error_est : Estimated error output vector [Re Im] - * RETURN : nothing - * - * DESCRIPTION : - * perform phase estimation from regenerated PTRS SC and channel compensated - * signal - *********************************************************************/ -void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_pusch_pdu_t *rel15_ul, - int16_t *ptrs_ch_p, - unsigned char Ns, - unsigned char symbol, - int16_t *rxF_comp, - uint32_t ***ptrs_gold_seq, - int16_t *error_est, - uint16_t *ptrs_sc) -{ - uint8_t is_ptrs_re = 0; - uint16_t re_cnt = 0; - uint16_t cnt = 0; - unsigned short nb_re_pusch = NR_NB_SC_PER_RB * rel15_ul->rb_size; - uint8_t K_ptrs = rel15_ul->pusch_ptrs.ptrs_freq_density; - uint16_t sc_per_symbol = (rel15_ul->rb_size + K_ptrs - 1)/K_ptrs; - int16_t *ptrs_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol)); - int16_t *dmrs_comp_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol)); - double abs = 0.0; - double real = 0.0; - double imag = 0.0; -#ifdef DEBUG_UL_PTRS - double alpha = 0; -#endif - /* generate PTRS RE for the symbol */ - nr_gen_ref_conj_symbols(ptrs_gold_seq[Ns][symbol],sc_per_symbol*2,ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK - - /* loop over all sub carriers to get compensated RE on ptrs symbols*/ - for (int re = 0; re < nb_re_pusch; re++) - { - is_ptrs_re = is_ptrs_subcarrier(re, - rel15_ul->rnti, - 0, - rel15_ul->dmrs_config_type, - K_ptrs, - rel15_ul->rb_size, - rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset, - 0,// start_re is 0 here - frame_parms->ofdm_symbol_size); - if(is_ptrs_re) - { - dmrs_comp_p[re_cnt*2] = rxF_comp[re *2]; - dmrs_comp_p[(re_cnt*2)+1] = rxF_comp[(re *2)+1]; - re_cnt++; - } - else - { - /* Skip PTRS symbols and keep data in a continuous vector */ - rxF_comp[cnt *2]= rxF_comp[re *2]; - rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1]; - cnt++; - } - }/* RE loop */ - /* update the total ptrs RE in a symbol */ - *ptrs_sc = re_cnt; - - /*Multiple compensated data with conj of PTRS */ - mult_cpx_vector(dmrs_comp_p, ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted - - /* loop over all ptrs sub carriers in a symbol */ - /* sum the error vector */ - for(int i = 0;i < sc_per_symbol; i++) - { - real+= ptrs_ch_p[(2*i)]; - imag+= ptrs_ch_p[(2*i)+1]; - } -#ifdef DEBUG_UL_PTRS - alpha = atan(imag/real); - printf("PTRS: Symbol %d atan(Im,real):= %f \n",symbol, alpha ); -#endif - /* mean */ - real /= sc_per_symbol; - imag /= sc_per_symbol; - /* absolute calculation */ - abs = sqrt(((real * real) + (imag * imag))); - /* normalized error estimation */ - error_est[0]= (real / abs)*(1<<15); - /* compensation in given by conjugate of estimated phase (e^-j*2*pi*fd*t)*/ - error_est[1]= (-1)*(imag / abs)*(1<<15); -#ifdef DEBUG_UL_PTRS - printf("PTRS: Estimated Symbol %d -> %d + j* %d \n",symbol, error_est[0], error_est[1] ); -#endif - /* free vectors */ - free(ptrs_p); - free(dmrs_comp_p); -} - - -/******************************************************************* - * - * NAME : nr_pusch_phase_interpolation - * - * PARAMETERS : *error_est : Data Pointer [Re Im Re Im ...] - * start_symbol : Start Symbol - * end_symbol : End Symbol - * RETURN : nothing - * - * DESCRIPTION : - * Perform Interpolation, extrapolation based upon the estimation - * location between the data Pointer Array. - * - *********************************************************************/ -void nr_pusch_phase_interpolation(int16_t *error_est, - uint8_t start_symbol, - uint8_t end_symbol - ) -{ - - int next = 0, prev = 0, candidates= 0, distance=0, leftEdge= 0, rightEdge = 0, getDiff =0 ; - double weight = 0.0; - double scale = 0.125 ; // to avoid saturation due to fixed point multiplication -#ifdef DEBUG_UL_PTRS - printf("PTRS: INT: Left limit %d, Right limit %d, Loop over %d Symbols \n", - start_symbol,end_symbol-1, (end_symbol -start_symbol)-1); -#endif - for(int i =start_symbol; i< end_symbol;i++) - { - /* Only update when an estimation is found */ - if( error_est[i*2] != 0 ) - { - /* if found a symbol then set next symbol also */ - next = nr_ptrs_find_next_estimate(error_est, i, end_symbol); - /* left extrapolation, if first estimate value is zero */ - if( error_est[i*2] == 0 ) - { - leftEdge = 1; - } - /* right extrapolation, if next is 0 before end symbol */ - if((next == 0) && (end_symbol > i)) - { - rightEdge = 1; - /* special case as no right extrapolation possible with DMRS on left */ - /* In this case take mean of most recent 2 estimated points */ - if(prev ==0) - { - prev = start_symbol -1; - next = start_symbol -2; - getDiff =1; - }else - { - /* for right edge previous is second last from right side */ - next = prev; - /* Set the current as recent estimation reference */ - prev = i; - } - } - /* update current symbol as prev for next symbol */ - if (rightEdge==0) - /* Set the current as recent estimation reference */ - prev = i; - } - /*extrapolation left side*/ - if(leftEdge) - { - distance = next - prev; - weight = 1.0/distance; - candidates = i; - for(int j = 1; j <= candidates; j++) - { - error_est[(i-j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) - - ((double)(error_est[next*2]) * scale * j * weight)); - error_est[((i-j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale* (distance + j) * weight) - - ((double)(error_est[((next*2)+1)]) * scale * j * weight)); -#ifdef DEBUG_UL_PTRS - printf("PTRS: INT: Left Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n", - (i-j),weight, error_est[(i-j)*2],error_est[((i-j)*2)+1], prev,next); -#endif - } - leftEdge = 0; - } - /* extrapolation at right side */ - else if (rightEdge ) - { - if(getDiff) - { - error_est[(i+1)*2] = ((1<<15) +(error_est[prev*2]) - error_est[next*2]); - error_est[((i+1)*2)+1]= error_est[(prev*2)+1] - error_est[(next*2)+1]; -#ifdef DEBUG_UL_PTRS - printf("PTRS: INT: Right Edge Special Case i= %d weight= %f %d + j*%d, Prev %d Next %d \n", - (i+1),weight, error_est[(i+1)*2],error_est[((i+1)*2)+1], prev,next); -#endif - i++; - } - else - { - distance = prev - next; - candidates = (end_symbol -1) - i; - weight = 1.0/distance; - for(int j = 1; j <= candidates; j++) - { - error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) - - ((double)(error_est[next*2]) * scale * j * weight)); - error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale * (distance + j) * weight) - - ((double)(error_est[((next*2)+1)]) * scale *j * weight)); -#ifdef DEBUG_UL_PTRS - printf("PTRS: INT: Right Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n", - (i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1], prev,next); -#endif - } - if(candidates > 1) - { - i+=candidates; - } - } - } - /* Interpolation between 2 estimated points */ - else if(next != 0 && ( error_est[2*i] == 0 )) - { - distance = next - prev; - weight = 1.0/distance; - candidates = next - i ; - for(int j = 0; j < candidates; j++) - { - - error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance - (j+1)) * weight) + - ((double)(error_est[next*2]) * scale * (j+1) * weight)); - error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale *(distance - (j+1)) * weight) + - ((double)(error_est[((next*2)+1)]) * scale *(j+1) * weight)); -#ifdef DEBUG_UL_PTRS - printf("PTRS: INT: Interpolation i= %d weight= %f %d + j*%d, Prev %d Next %d\n", - (i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1],prev,next); -#endif - } - if(candidates > 1) - { - i+=candidates-1; - } - }// interpolation - }// symbol loop -} - -/* Find the next non zero Real value in a complex vector */ -int nr_ptrs_find_next_estimate(int16_t *error_est, - uint8_t counter, - uint8_t end_symbol) -{ - for (int i = counter +1 ; i< end_symbol; i++) - { - if( error_est[2*i] != 0) - { - return i; - } - } - return 0; + }// last symbol check + }//Antenna loop } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 0f71487e36..a463e21839 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -53,28 +53,10 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, + NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t *rel15_ul, uint8_t ulsch_id, uint8_t nr_tti_rx, - uint8_t dmrs_symbol_flag, unsigned char symbol, uint32_t nb_re_pusch); - -void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms, - nfapi_nr_pusch_pdu_t *rel15_ul, - int16_t *ptrs_ch_p, - unsigned char Ns, - unsigned char symbol, - int16_t *rxF_comp, - uint32_t ***ptrs_gold_seq, - int16_t *error_est, - uint16_t *ptrs_sc); - -void nr_pusch_phase_interpolation(int16_t *error_est, - uint8_t start_symbol, - uint8_t end_symbol); - -int nr_ptrs_find_next_estimate(int16_t *error_est, - uint8_t counter, - uint8_t end_symbol); #endif diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index 415e6adfa2..03a37e2b27 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -37,6 +37,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, uint16_t start_sc, + uint16_t ofdm_symbol_size, uint8_t numDmrsCdmGrpsNoData, uint8_t dmrs_type) { uint8_t delta; @@ -44,7 +45,7 @@ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, if (k>start_sc) diff = k-start_sc; else - diff = start_sc-k; + diff = (ofdm_symbol_size-start_sc)+k; for (int i = 0; i>symbol)&0x01 ) - { + for(uint8_t symbol = counter; symbol < end_symbol; symbol++) { + if((ul_dmrs_symb_pos >> symbol) & 0x01 ) { return symbol; } - return 0; + } + return -1; } @@ -378,9 +379,30 @@ int get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, ui uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb) { uint8_t tmp = 0; - for (int i = 0; i < nb_symb; i++) - { + for (int i = 0; i < nb_symb; i++) { tmp += (l_prime_mask >> i) & 0x01; } return tmp; } + +/* return the position of valid dmrs symbol in a slot for channel compensation */ +int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter) +{ + int8_t symbIdx = -1; + /* if current symbol is DMRS then return this index */ + if(is_dmrs_symbol(counter, dmrs_symb_pos ) ==1) { + return counter; + } + /* find previous DMRS symbol */ + for(int8_t symbol = counter;symbol >=0 ; symbol--) { + if((1< 0) { + symbIdx = symbol; + break; + } + } + /* if there is no previous dmrs available then find the next possible*/ + if(symbIdx == -1) { + symbIdx = get_next_dmrs_symbol_in_slot(dmrs_symb_pos,counter,15); + } + return symbIdx; +} diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index c76f58ad18..b9e9ca6f0d 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -58,9 +58,16 @@ uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_ uint8_t allowed_xlsch_re_in_dmrs_symbol(uint16_t k, uint16_t start_sc, + uint16_t ofdm_symbol_size, uint8_t numDmrsCdmGrpsNoData, uint8_t dmrs_type); +void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order); +int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol); +uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb); +int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter); + +static inline uint8_t is_dmrs_symbol(uint8_t l, uint16_t dmrsSymbMask ) { return ((dmrsSymbMask >> l) & 0x1); } #undef EXTERN #endif /* DMRS_NR_H */ diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 3e758c4fa5..5d62f9dbb9 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -121,18 +121,18 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, array_of_w *wf; array_of_w *wt; - config_type = 0; //to be updated by higher layer + config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; - wf = (config_type==0) ? wf1 : wf2; - wt = (config_type==0) ? wt1 : wt2; + wf = (config_type==pdsch_dmrs_type1) ? wf1 : wf2; + wt = (config_type==pdsch_dmrs_type1) ? wt1 : wt2; if (config_type > 1) LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type); - if ((p>=1000) && (p<((config_type==0) ? 1008 : 1012))) { + if ((p>=1000) && (p<((config_type==pdsch_dmrs_type1) ? 1008 : 1012))) { if (ue->frame_parms.Ncp == NORMAL) { - for (int i=0; i=1000) && (p<1008)) { + if (gNB->frame_parms.Ncp == NORMAL) { + nb_dmrs = NR_NB_SC_PER_RB/2; // for DMRS TYPE 1 - 6 DMRS REs present per RB + for (int i=dmrs_offset; iframe_parms.Nid_cell; Lmax = ue->frame_parms.Lmax; @@ -37,24 +38,12 @@ void nr_gold_pbch(PHY_VARS_NR_UE* ue) i_ssb = l & (Lmax-1); i_ssb2 = i_ssb + (n_hf<<2); - x1 = 1 + (1<<31); + reset = 1; x2 = (1<<11) * (i_ssb2 + 1) * ((Nid>>2) + 1) + (1<<6) * (i_ssb2 + 1) + (Nid&3); - x2 = x2 ^ ((x2 ^ (x2>>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); - } 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); - ue->nr_gold_pbch[n_hf][l][n] = x1 ^ x2; + ue->nr_gold_pbch[n_hf][l][n] = lte_gold_generic(&x1, &x2, reset); + reset = 0; } } @@ -69,52 +58,38 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue, unsigned char ns,l; unsigned int n,x1,x2,x2tmp0; unsigned int nid; + uint8_t reset; - if (n_idDMRS) - nid = n_idDMRS; - else - nid = ue->frame_parms.Nid_cell; + if (n_idDMRS) + nid = n_idDMRS; + else + nid = ue->frame_parms.Nid_cell; - for (ns=0; ns<20; ns++) { + for (ns=0; nsframe_parms.slots_per_frame; 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<52; 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); - ue->nr_gold_pdcch[0][ns][l][n] = x1^x2; - // if (ns==1 && l==0) printf("n=%d : c %x\n",n,x1^x2); - } - } + reset = 1; + x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17; + x2 = (x2tmp0+(nid<<1))%(1<<31); //cinit + + for (n=0; nnr_gold_pdcch[0][ns][l][n] = lte_gold_generic(&x1, &x2, reset); + reset = 0; + } } + } } void nr_gold_pdsch(PHY_VARS_NR_UE* ue, - unsigned short lbar, - unsigned short *n_idDMRS, - unsigned short length_dmrs) + unsigned char ns, + unsigned short *n_idDMRS) { - unsigned char ns,l; + unsigned char l; unsigned int n,x1,x2,x2tmp0; int nscid; unsigned int nid; + uint8_t reset; /// to be updated from higher layer //unsigned short lbar = 0; @@ -124,40 +99,19 @@ void nr_gold_pdsch(PHY_VARS_NR_UE* ue, nid = n_idDMRS[nscid]; else nid = ue->frame_parms.Nid_cell; - - //printf("gold pdsch nid %d lbar %d\n",nid,lbar); - for (ns=0; ns<20; ns++) { + //printf("gold pdsch nid %d lbar %d\n",nid,lbar); - for (l=0; lframe_parms.symbols_per_slot; l++) { - 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); - x2=x2 ^ ((x2 ^ (x2>>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); - ue->nr_gold_pdsch[nscid][ns][l][n] = x1^x2; - // if ((ns==2)&&(l==0)) - //printf("n=%d : c %x\n",n,x1^x2); - } + reset = 1; + x2tmp0 = ((ue->frame_parms.symbols_per_slot*ns+l+1)*((nid<<1)+1))<<17; + x2 = (x2tmp0+(nid<<1)+nscid)%(1<<31); //cinit + LOG_D(PHY,"UE DMRS slot %d, symb %d, x2 %x, nscid %d\n",ns,l,x2,nscid); + for (n=0; nnr_gold_pdsch[0][ns][l][nscid][n] = lte_gold_generic(&x1, &x2, reset); + reset = 0; } } } diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index f82a7880bb..aedc535c29 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -53,14 +53,24 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, uint8_t dmrs_type); void init_scrambling_luts(void); -void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order); -uint8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol); -uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb); - void nr_generate_modulation_table(void); extern __m64 byte2m64_re[256]; extern __m64 byte2m64_im[256]; extern __m128i byte2m128i[256]; + + +int nr_pusch_lowpaprtype1_dmrs_rx(PHY_VARS_gNB *gNB, + unsigned int Ns, + int16_t *dmrs_seq, + int32_t *output, + unsigned short p, + unsigned char lp, + unsigned short nb_pusch_rb, + uint32_t re_offset, + uint8_t dmrs_type); + + + #endif diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index 785252126a..b50c9a7bc9 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -34,7 +34,7 @@ #include #include "dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" - +#include "PHY/NR_REFSIG/nr_refsig.h" /***********************************************************************/ @@ -180,93 +180,249 @@ uint8_t is_ptrs_subcarrier(uint16_t k, return 0; } - -/* -int main(int argc, char const *argv[]) +/* return the total number of ptrs symbol in a slot */ +uint8_t get_ptrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t start_symb, uint16_t nb_symb) { - - dmrs_UplinkConfig_t dmrs_Uplink_Config; - ptrs_UplinkConfig_t ptrs_Uplink_Config; - uint8_t resourceElementOffset; - uint8_t dmrs_antenna_port; - uint8_t L_ptrs, K_ptrs; - int16_t k_RE_ref; - uint16_t N_RB, ptrs_symbols, ofdm_symbol_size, k; - uint8_t duration_in_symbols, I_mcs; - uint8_t start_symbol, l; - uint8_t ptrs_symbol_flag; - uint16_t n_rnti; - - dmrs_Uplink_Config.pusch_dmrs_type = pusch_dmrs_type1; - dmrs_Uplink_Config.pusch_dmrs_AdditionalPosition = pusch_dmrs_pos1; - dmrs_Uplink_Config.pusch_maxLength = pusch_len2; - - ptrs_Uplink_Config.timeDensity.ptrs_mcs1 = 0; // setting MCS values to 0 indicate abscence of time_density field in the configuration - ptrs_Uplink_Config.timeDensity.ptrs_mcs2 = 0; - ptrs_Uplink_Config.timeDensity.ptrs_mcs3 = 0; - ptrs_Uplink_Config.frequencyDensity.n_rb0 = 0; // setting N_RB values to 0 indicate abscence of frequency_density field in the configuration - ptrs_Uplink_Config.frequencyDensity.n_rb1 = 0; - ptrs_Uplink_Config.resourceElementOffset = 0; - - n_rnti = 0x1234; - resourceElementOffset = 0; - ptrs_symbols = 0; - dmrs_antenna_port = 0; - N_RB = 50; - duration_in_symbols = 14; - ofdm_symbol_size = 2048; - I_mcs = 9; - start_symbol = 0; - ptrs_symbol_flag = 0; - - k_RE_ref = get_kRE_ref(dmrs_antenna_port, dmrs_Uplink_Config.pusch_dmrs_type, resourceElementOffset); - - K_ptrs = get_K_ptrs(&ptrs_Uplink_Config, N_RB); - - L_ptrs = get_L_ptrs(&ptrs_Uplink_Config, I_mcs); - - set_ptrs_symb_idx(&ptrs_symbols, - &ptrs_Uplink_Config, - &dmrs_Uplink_Config, - 1, - duration_in_symbols, - start_symbol, - L_ptrs, - ofdm_symbol_size); - - printf("PTRS OFDM symbol indicies: "); - - for (l = start_symbol; l < start_symbol + duration_in_symbols; l++){ - - ptrs_symbol_flag = is_ptrs_symbol(l, - 0, - n_rnti, - N_RB, - duration_in_symbols, - dmrs_antenna_port, - K_ptrs, - ptrs_symbols, - dmrs_Uplink_Config.pusch_dmrs_type, - &ptrs_Uplink_Config); - - if (ptrs_symbol_flag == 1) - printf(" %d ", l); - + uint8_t tmp = 0; + for (int i = start_symb; i <= nb_symb; i++) + { + tmp += (l_prime_mask >> i) & 0x01; } + return tmp; +} - printf("\n"); - - printf("PTRS subcarrier indicies: "); - - for (k = 0; k < N_RB*12; k++){ - - if (is_ptrs_subcarrier(k, K_ptrs, n_rnti, N_RB, k_RE_ref) == 1) - printf(" %d ", k); - +/* return the position of next ptrs symbol in a slot */ +int8_t get_next_ptrs_symbol_in_slot(uint16_t ptrs_symb_pos, uint8_t counter, uint8_t nb_symb) +{ + for(int8_t symbol = counter; symbol < nb_symb; symbol++) { + if((ptrs_symb_pos >>symbol)&0x01 ) { + return symbol; } + } + return -1; +} - printf("\n"); +/* get the next nearest estimate from DMRS or PTRS */ +int8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, uint8_t counter,uint8_t nb_symb) +{ + int8_t nextPtrs = get_next_ptrs_symbol_in_slot(ptrsSymbPos, counter,nb_symb); + int8_t nextDmrs = get_next_dmrs_symbol_in_slot(dmrsSymbPos, counter,nb_symb); + if(nextDmrs == -1) { + return nextPtrs; + } + /* Special case when DMRS is next valid estimation */ + if(nextPtrs == -1) { + return nextDmrs; + } + return (nextPtrs > nextDmrs)?nextDmrs:nextPtrs; +} +/******************************************************************* + * + * NAME : nr_ptrs_cpe_estimation + * + * PARAMETERS : K_ptrs : K value for PTRS + * ptrsReOffset : RE offset for PTRS + * dmrsConfigType: DMRS configuration type + * nb_rb : No. of resource blocks + * rnti : RNTI + * ptrs_ch_p : pointer to ptrs channel structure + * Ns : + * symbol : OFDM symbol + * ofdm_symbol_size: OFDM Symbol Size + * rxF_comp : pointer to channel compensated signal + * gold_seq : Gold sequence pointer + * error_est : Estimated error output vector [Re Im] + * ptrs_sc : Total PTRS RE in a symbol + * RETURN : nothing + * + * DESCRIPTION : + * perform phase estimation from regenerated PTRS SC and channel compensated + * signal + *********************************************************************/ +void nr_ptrs_cpe_estimation(uint8_t K_ptrs, + uint8_t ptrsReOffset, + uint8_t dmrsConfigType, + uint16_t nb_rb, + uint16_t rnti, + int16_t *ptrs_ch_p, + unsigned char Ns, + unsigned char symbol, + uint16_t ofdm_symbol_size, + int16_t *rxF_comp, + uint32_t *gold_seq, + int16_t *error_est, + int32_t *ptrs_sc) +{ +//#define DEBUG_PTRS 1 + uint8_t is_ptrs_re = 0; + uint16_t re_cnt = 0; + uint16_t cnt = 0; + unsigned short nb_re_pdsch = NR_NB_SC_PER_RB * nb_rb; + uint16_t sc_per_symbol = (nb_rb + K_ptrs - 1)/K_ptrs; + int16_t *ptrs_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol)); + int16_t *dmrs_comp_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol)); + double abs = 0.0; + double real = 0.0; + double imag = 0.0; +#ifdef DEBUG_PTRS + double alpha = 0; +#endif + /* generate PTRS RE for the symbol */ + nr_gen_ref_conj_symbols(gold_seq,sc_per_symbol*2,ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK + + /* loop over all sub carriers to get compensated RE on ptrs symbols*/ + for (int re = 0; re < nb_re_pdsch; re++) { + is_ptrs_re = is_ptrs_subcarrier(re, + rnti, + 0, + dmrsConfigType, + K_ptrs, + nb_rb, + ptrsReOffset, + 0,// start_re is 0 here + ofdm_symbol_size); + if(is_ptrs_re) { + dmrs_comp_p[re_cnt*2] = rxF_comp[re *2]; + dmrs_comp_p[(re_cnt*2)+1] = rxF_comp[(re *2)+1]; + re_cnt++; + } + else { + /* Skip PTRS symbols and keep data in a continuous vector */ + rxF_comp[cnt *2]= rxF_comp[re *2]; + rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1]; + cnt++; + } + }/* RE loop */ + /* update the total ptrs RE in a symbol */ + *ptrs_sc = re_cnt; + + /*Multiple compensated data with conj of PTRS */ + mult_cpx_vector(dmrs_comp_p, ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted + + /* loop over all ptrs sub carriers in a symbol */ + /* sum the error vector */ + for(int i = 0;i < sc_per_symbol; i++) { + real+= ptrs_ch_p[(2*i)]; + imag+= ptrs_ch_p[(2*i)+1]; + } +#ifdef DEBUG_PTRS + alpha = atan(imag/real); + printf("[PHY][PTRS]: Symbol %d atan(Im,real):= %f \n",symbol, alpha ); +#endif + /* mean */ + real /= sc_per_symbol; + imag /= sc_per_symbol; + /* absolute calculation */ + abs = sqrt(((real * real) + (imag * imag))); + /* normalized error estimation */ + error_est[0]= (real / abs)*(1<<15); + /* compensation in given by conjugate of estimated phase (e^-j*2*pi*fd*t)*/ + error_est[1]= (-1)*(imag / abs)*(1<<15); +#ifdef DEBUG_PTRS + printf("[PHY][PTRS]: Estimated Symbol %d -> %d + j* %d \n",symbol, error_est[0], error_est[1] ); +#endif + /* free vectors */ + free(ptrs_p); + free(dmrs_comp_p); +} + + +/******************************************************************* + * + * NAME : nr_ptrs_process_slot + * + * PARAMETERS : dmrsSymbPos DMRS symbol index mask per slot + * ptrsSymbpos PTRS symbol index mask per slot + * estPerSymb Estimated CPE pointer + * startSymbIdx First symbol index in a slot + * noSymb total number of OFDM symbols in a slot + * RETURN : True if slot is process correctly + * DESCRIPTION : + * Process whole slot and interpolate or extrapolate estimation for the symbols + * where there is neither PTRS nor DMRS configured + * + *********************************************************************/ +int8_t nr_ptrs_process_slot(uint16_t dmrsSymbPos, + uint16_t ptrsSymbPos, + int16_t *estPerSymb, + uint16_t startSymbIdx, + uint16_t noSymb) +{ + double slope[2] = {0,0}; + double *slope_p = &slope[0]; + uint8_t symbInSlot = startSymbIdx + noSymb; + int8_t rightRef = 0; + int8_t leftRef = 0; + int8_t tmp = 0; + for(uint8_t symb = startSymbIdx; symb %4d %4d from Slope (%4f %4f)\n", start+i,error_est[(start+i)*2],error_est[((start +i)*2)+1], + slope_p[0],slope_p[1]); +#endif + } +} diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h index e8a4e61232..41acde0d06 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.h +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -80,6 +80,31 @@ uint8_t is_ptrs_subcarrier(uint16_t k, static inline uint8_t is_ptrs_symbol(uint8_t l, uint16_t ptrs_symbols) { return ((ptrs_symbols >> l) & 1); } +uint8_t get_ptrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t start_symb, uint16_t nb_symb); +int8_t get_next_ptrs_symbol_in_slot(uint16_t ptrsSymbPos, uint8_t counter, uint8_t nb_symb); +int8_t get_next_estimate_in_slot(uint16_t ptrsSymbPos,uint16_t dmrsSymbPos, uint8_t counter,uint8_t nb_symb); +int8_t nr_ptrs_process_slot(uint16_t dmrsSymbPos, + uint16_t ptrsSymbPos, + int16_t *estPerSymb, + uint16_t startSymbIdx, + uint16_t noSymb + ); +/* general function to estimate common phase error based upon PTRS */ +void nr_ptrs_cpe_estimation(uint8_t K_ptrs, + uint8_t ptrsReOffset, + uint8_t dmrsConfigType, + uint16_t nb_rb, + uint16_t rnti, + int16_t *ptrs_ch_p, + unsigned char Ns, + unsigned char symbol, + uint16_t ofdm_symbol_size, + int16_t *rxF_comp, + uint32_t *gold_seq, + int16_t *error_est, + int32_t *ptrs_sc); +void get_slope_from_estimates(uint8_t start, uint8_t end, int16_t *est_p, double *slope_p); +void ptrs_estimate_from_slope(int16_t *error_est, double *slope_p, uint8_t start, uint8_t end); #endif /* PTRS_NR_H */ diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 93a64051de..83b43c54a0 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -61,9 +61,8 @@ void nr_gold_pdcch(PHY_VARS_NR_UE* ue, unsigned short length_dmrs); void nr_gold_pdsch(PHY_VARS_NR_UE* ue, - unsigned short lbar, - unsigned short *n_idDMRS, - unsigned short length_dmrs); + unsigned char ns, + unsigned short *n_idDMRS); void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t *N_n_scid, diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index c260abd071..12d91ed3d1 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -92,13 +92,7 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]); -int _do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, - int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], - uint8_t doPss, uint8_t doSss, - uint8_t subframe); - -int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric, uint8_t *phase_max); +int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max); #undef INIT_VARIABLES_SSS_NR_H #undef EXTERN diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c index 8521a2618f..4a419ae926 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.c @@ -108,6 +108,39 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, return rv_overbar; } +/******************************************************************* +* +* NAME : get_index_for_dmrs_lowpapr_seq +* +* PARAMETERS : num_dmrs_res - Total number of DMRS RES possible in allocated RBs +* +* +* RETURN : returns index of array dmrs_ul_allocated_res +* +* DESCRIPTION : finds the index which in turn is used to index into dmrs low papr sequences +* +*********************************************************************/ + +int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res) { + + int16_t index = -1; + + if (num_dmrs_res >= dmrs_ul_allocated_res[(MAX_INDEX_DMRS_UL_ALLOCATED_REs-1)]) + index = MAX_INDEX_DMRS_UL_ALLOCATED_REs-1; + else + index = (num_dmrs_res/6) -1; + + for (;index >= 0; index--) { + if (dmrs_ul_allocated_res[index] == num_dmrs_res) + break; + + } + + LOG_D(PHY, "num_dmrs_res: %d INDEX RETURNED: %d", num_dmrs_res, index); + return index; + +} + /******************************************************************* * * NAME : base_sequence_36_or_larger @@ -126,13 +159,19 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, unsigned int u, unsigned int v, - unsigned int scaling) + unsigned int scaling, unsigned int if_dmrs_seq) { int16_t *rv_overbar; - unsigned int N_ZC; + unsigned int N_ZC, M_ZC; double q_overbar, x; unsigned int q,m,n; - unsigned int M_ZC = ul_allocated_re[Msc_RS]; + + + if (if_dmrs_seq) + M_ZC = dmrs_ul_allocated_res[Msc_RS]; + else + M_ZC = ul_allocated_re[Msc_RS]; + rv_overbar = malloc16(IQ_SIZE*M_ZC); if (rv_overbar == NULL) { @@ -140,7 +179,11 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, assert(0); } - N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */ + if (if_dmrs_seq) + N_ZC = dmrs_ref_ul_primes[Msc_RS]; + else + N_ZC = ref_ul_primes[Msc_RS]; /* The length N_ZC is given by the largest prime number such that N_ZC < M_ZC */ + q_overbar = N_ZC * (u+1)/(double)31; @@ -159,19 +202,24 @@ int16_t *base_sequence_36_or_larger(unsigned int Msc_RS, return rv_overbar; } -/******************************************************************* -* -* NAME : generate_ul_srs_sequences -* -* PARAMETERS : scaling to apply -* -* RETURN : none -* -* DESCRIPTION : uplink reference signal sequences generation -* which are Low-PAPR base sequences -* see TS 38.211 5.2.2 Low-PAPR sequence generation -* -*********************************************************************/ +void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling) +{ + unsigned int u,Msc_RS; + unsigned int v = 0; // sequence hopping and group hopping are not supported yet + + for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) { + for (u=0; u < U_GROUP_NUMBER; u++) { + gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling); + } + } + + for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { + for (u=0; u < U_GROUP_NUMBER; u++) { + gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1); + } + } +} + void generate_ul_reference_signal_sequences(unsigned int scaling) { @@ -184,10 +232,13 @@ void generate_ul_reference_signal_sequences(unsigned int scaling) #endif + for (Msc_RS=0; Msc_RS <= INDEX_SB_LESS_32; Msc_RS++) { - v = 0; + v = 0; for (u=0; u < U_GROUP_NUMBER; u++) { rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling); + dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_less_than_36(ul_allocated_re[Msc_RS], u, scaling); + #if 0 sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]); sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]); @@ -198,10 +249,19 @@ void generate_ul_reference_signal_sequences(unsigned int scaling) } } + for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { + v = 0; // neither group hopping or sequnce hopping is supported for PUSCH DMRS hence v = 0 + for (u=0; u < U_GROUP_NUMBER; u++) { + dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 1); + } + + } + for (Msc_RS=INDEX_SB_LESS_32+1; Msc_RS < SRS_SB_CONF; Msc_RS++) { for (u=0; u < U_GROUP_NUMBER; u++) { - for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) { - rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling); + for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) { + rv_ul_ref_sig[u][v][Msc_RS] = base_sequence_36_or_larger(Msc_RS, u, v, scaling, 0); + #if 0 sprintf(output_file, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]); sprintf(sequence_name, "rv_seq_%d_%d_%d.m", u, v, ul_allocated_re[Msc_RS]); @@ -212,8 +272,11 @@ void generate_ul_reference_signal_sequences(unsigned int scaling) } } } + + } + /******************************************************************* * * NAME : free_ul_reference_signal_sequences @@ -233,7 +296,33 @@ void free_ul_reference_signal_sequences(void) for (v=0; v < V_BASE_SEQUENCE_NUMBER; v++) { if (rv_ul_ref_sig[u][v][Msc_RS]) free16(rv_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*ul_allocated_re[Msc_RS]); + if ((v==0) && (Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs)) + if (dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS]) + free16(dmrs_lowpaprtype1_ul_ref_sig[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]); } } } } +/******************************************************************* +* +* NAME : free_gnb_lowpapr_sequences +* +* PARAMETERS : none +* +* RETURN : none +* +* DESCRIPTION : free of uplink reference signal sequences +* +*********************************************************************/ +void free_gnb_lowpapr_sequences(void) +{ + unsigned int u,v,Msc_RS; + for (Msc_RS=0; Msc_RS < MAX_INDEX_DMRS_UL_ALLOCATED_REs; Msc_RS++) { + v=0; + for (u=0; u < U_GROUP_NUMBER; u++) { + if (gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS]) + free16(gNB_dmrs_lowpaprtype1_sequence[u][v][Msc_RS],2*sizeof(int16_t)*dmrs_ul_allocated_res[Msc_RS]); + } + } +} + diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h index dd967e8e5e..44d30da8f3 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h @@ -38,6 +38,10 @@ #include "PHY/NR_REFSIG/ss_pbch_nr.h" +#include "PHY/defs_nr_common.h" +#include "PHY/defs_gNB.h" + + #ifdef DEFINE_VARIABLES_LOWPAPR_SEQUENCES_NR_H #define EXTERN #define INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H @@ -255,7 +259,10 @@ const char phi_M_ZC_24[24*U_GROUP_NUMBER] ; /************** FUNCTION ******************************************/ -int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling); + +int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq); + + int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling); /*! \brief This function generate the sounding reference symbol (SRS) for the uplink. @@ -265,6 +272,72 @@ int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned void generate_ul_reference_signal_sequences(unsigned int scaling); void free_ul_reference_signal_sequences(void); + + +// Supported for 100Mhz configuration - which has max 273 RBs +#define MAX_INDEX_DMRS_UL_ALLOCATED_REs 53 + + +const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs] +/* Number of possible DMRS REs based on PRBs allocated for PUSCH. Array has values until 273 RBs (100Mhz BW) + Number of PUSCH RBs allocated should be able to be expressed as 2topowerofn*3topowerofn*5tothepowerofn + According to 3GPP spec 38.211 section 6.3.1.4 + Table used in calculating DMRS low papr type1 sequence for transform precoding */ +#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H += { +/*RBs 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, */ + 6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96, + +/*RBs 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48, 50, */ + 108, 120, 144, 150, 162, 180, 192, 216, 240, 270, 288, 300, + +/*RBs 54, 60, 64, 72 75, 80, 81, 90, 96, 100, (Bw 40Mhz) */ + 324, 360, 384, 432, 450, 480, 486, 540, 576, 600, + +/*RBs 108, 120 125 128 135 144 150 160 162 180 192 200 */ + 648, 720, 750, 768, 810, 864, 900, 960, 972, 1080, 1152, 1200, + +/*RBs 216 225 240 243 250 256 270 supported until 100Mhz */ + 1296, 1350, 1440, 1458, 1500, 1536, 1620 + +} +#endif +; + +/* Table of largest prime number N_ZC < possible DMRS REs M_ZC, this array has values until 100Mhz + According to 3GPP spec 38.211 section 5.2.2.1 + Table used in calculating DMRS low papr type1 sequence for transform precoding */ +const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs] +#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H += { +/*DMRS REs 6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96, */ + 5, 11, 17, 23, 29, 31, 47, 53, 59, 71, 89, 89, + +/*DMRS REs 108, 120, 144, 150, 162, 180, 192, 216, 240, 270, 288, 300, */ + 107, 113, 139, 149, 157, 179, 191, 211, 239, 269, 283, 293, + +/*DMRS REs 324, 360, 384, 432, 450, 480, 486, 540, 576, 600, */ + 317, 359, 383, 431, 449, 479, 479, 523, 571, 599, + +/*DMRS REs 648, 720, 750, 768, 810, 864, 900, 960, 972, 1080, 1152, 1200, */ + 647, 719, 743, 761, 809, 863, 887, 953, 971, 1069, 1151, 1193, + +/*DMRS REs 1296, 1350, 1440, 1458, 1500, 1536 1620 supported until 100Mhz */ + 1291, 1327, 1439, 1453, 1499, 1531, 1619 + + +} +#endif +; + +/// PUSCH DMRS for transform precoding +int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs]; +int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res); +void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling); +void free_gnb_lowpapr_sequences(void); + + #undef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H #undef EXTERN diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 2d79aa8fbd..469415908f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -30,6 +30,7 @@ * \warning */ +#include #include "nr_dci.h" #include "nr_dlsch.h" #include "nr_sch_dmrs.h" @@ -64,54 +65,37 @@ void nr_pdcch_scrambling(uint32_t *in, } } - - -uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB, - nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, - nfapi_nr_dl_tti_pdcch_pdu *ul_dci_pdu, - uint32_t **gold_pdcch_dmrs, - int32_t *txdataF, - int16_t amp, - NR_DL_FRAME_PARMS frame_parms) { +void nr_generate_dci(PHY_VARS_gNB *gNB, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, + uint32_t **gold_pdcch_dmrs, + int32_t *txdataF, + int16_t amp, + NR_DL_FRAME_PARMS frame_parms) { int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration uint16_t cset_start_sc; uint8_t cset_start_symb, cset_nsymb; int k,l,k_prime,dci_idx, dmrs_idx; - /*First iteration: single DCI*/ - - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15=NULL; - // find coreset descriptor int rb_offset; int n_rb; - AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n"); - 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_rel15; - - nr_fill_cce_list(gNB,0,pdcch_pdu_rel15); - - get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); - // compute rb_offset and n_prb based on frequency allocation - + nr_fill_cce_list(gNB,0,pdcch_pdu_rel15); + get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); + cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB; 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 + rb_offset)*NR_NB_SC_PER_RB; - } else - cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB; + cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB; + } 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*/ + const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d]; cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; cset_nsymb = pdcch_pdu_rel15->DurationSymbols; @@ -119,11 +103,8 @@ uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB, 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->dci_pdu.AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) - uint32_t encoded_length = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE) + uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE) + uint32_t encoded_length = dci_pdu->AggregationLevel*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 @@ -145,19 +126,19 @@ uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB, // CRC attachment + Scrambling + Channel coding + Rate matching uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; - uint16_t n_RNTI = pdcch_pdu_rel15->dci_pdu.RNTI[d]; - uint16_t Nid = pdcch_pdu_rel15->dci_pdu.ScramblingId[d]; - uint16_t scrambling_RNTI = pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[d]; + uint16_t n_RNTI = dci_pdu->RNTI; + uint16_t Nid = dci_pdu->ScramblingId; + uint16_t scrambling_RNTI = dci_pdu->ScramblingRNTI; t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, - pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d], - pdcch_pdu_rel15->dci_pdu.AggregationLevel[d], + dci_pdu->PayloadSizeBits, + dci_pdu->AggregationLevel, 0,NULL); - polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d], (void*)encoder_output, n_RNTI,1,currentPtr); + polar_encoder_fast((uint64_t*)dci_pdu->Payload, (void*)encoder_output, n_RNTI,1,currentPtr); #ifdef DEBUG_CHANNEL_CODING - printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]); + printf("polar rnti %x,length %d, L %d\n",n_RNTI, dci_pdu->PayloadSizeBits,pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]); printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", - ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[1]); + ((uint64_t*)dci_pdu->Payload)[0], ((uint64_t*)dci_pdu->Payload)[1]); printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); for (int i=0; i>5; i++) @@ -183,64 +164,106 @@ uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB, 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 reg_idx0 = pdcch_pdu_rel15->dci_pdu.CceIndex[d]*NR_NB_REG_PER_CCE; - uint8_t nb_regs = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*NR_NB_REG_PER_CCE; + + // Get cce_list indices by reg_idx in ascending order + int reg_list_index = 0; + int reg_list_order[NR_MAX_PDCCH_AGG_LEVEL] = {}; + for (int p = 0; p < NR_MAX_PDCCH_AGG_LEVEL; p++) { + for(int p2 = 0; p2 < dci_pdu->AggregationLevel; p2++) { + if(gNB->cce_list[d][p2].reg_list[0].reg_idx == p * NR_NB_REG_PER_CCE) { + reg_list_order[reg_list_index] = p2; + reg_list_index++; + break; + } + } + } /*Mapping the encoded DCI along with the DMRS */ - for (int reg_idx=reg_idx0; reg_idx<(nb_regs+reg_idx0); reg_idx++) { - k = cset_start_sc + (12*reg_idx/cset_nsymb); - - if (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] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; + for (int cce_count = 0; cce_count < dci_pdu->AggregationLevel; cce_count ++) { + + int8_t cce_idx = reg_list_order[cce_count]; + + for (int reg_in_cce_idx = 0; reg_in_cce_idx < NR_NB_REG_PER_CCE; reg_in_cce_idx++) { + + k = cset_start_sc + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx; + + if (k >= frame_parms.ofdm_symbol_size) + k -= frame_parms.ofdm_symbol_size; + + l = cset_start_symb + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].symb_idx; + + // 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 =gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx * 3; + else + dmrs_idx = (gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].reg_idx + rb_offset) * 3; + + k_prime = 0; + + for (int m = 0; m < NR_NB_SC_PER_RB; m++) { + if (m == (k_prime << 2) + 1) { // DMRS if not already mapped + ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] = + (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15; + ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] = + (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15; + #ifdef DEBUG_PDCCH_DMRS printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); #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; + + 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 - + dci_idx++; + } + + k++; + + if (k >= frame_parms.ofdm_symbol_size) + k -= frame_parms.ofdm_symbol_size; + + } // m + } // reg_in_cce_idx + } // cce_count + + LOG_D(PHY, + "DCI: payloadSize = %d | payload = %llx\n", + dci_pdu->PayloadSizeBits, + *(unsigned long long *)dci_pdu->Payload); } // for (int d=0;dnumDlDci;d++) - return 0; +} + +void nr_generate_dci_top(PHY_VARS_gNB *gNB, + nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, + nfapi_nr_dl_tti_pdcch_pdu *ul_dci_pdu, + uint32_t **gold_pdcch_dmrs, + int32_t *txdataF, + int16_t amp, + NR_DL_FRAME_PARMS frame_parms) { + + AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n"); + + if (pdcch_pdu && ul_dci_pdu) { + nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); + nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); + } + else if (pdcch_pdu) + nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); + else + nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 288f525219..1b57acc6f4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -29,7 +29,7 @@ uint16_t nr_get_dci_size(nfapi_nr_dci_format_e format, nfapi_nr_rnti_type_e rnti_type, uint16_t N_RB); -uint8_t nr_generate_dci_top(PHY_VARS_gNB *gNB, +void nr_generate_dci_top(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, nfapi_nr_dl_tti_pdcch_pdu *ul_pdcch_pdu, uint32_t **gold_pdcch_dmrs, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index 2b64a3062c..3814c78295 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -142,7 +142,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_r AssertFatal(N_reg > 0,"N_reg cannot be 0\n"); for (int d=0;dnumDlDci;d++) { - int L = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]; + int L = pdcch_pdu_rel15->dci_pdu[d].AggregationLevel; if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); @@ -153,10 +153,10 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m, nfapi_nr_dl_tti_pdcch_pdu_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->dci_pdu.CceIndex[d]); + LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu[d].CceIndex); for (uint8_t cce_idx=0; cce_idxcce_list[d][cce_idx]; - cce->cce_idx = pdcch_pdu_rel15->dci_pdu.CceIndex[d] + cce_idx; + cce->cce_idx = pdcch_pdu_rel15->dci_pdu[d].CceIndex + cce_idx; LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { @@ -236,25 +236,24 @@ void nr_fill_dci(PHY_VARS_gNB *gNB, for (int i=0;inumDlDci;i++) { - //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i]; + //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload; - int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu.RNTI[i],gNB,SEARCH_EXIST_OR_FREE); + int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu[i].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",(unsigned int)pdcch_pdu_rel15->dci_pdu.RNTI[i],dlsch_id); + LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu[i].RNTI,dlsch_id); return; } dlsch = gNB->dlsch[dlsch_id][0]; - int num_slots_tdd = (gNB->frame_parms.slots_per_frame)>>(7-gNB->gNB_config.tdd_table.tdd_period.value); - int harq_pid = slot % num_slots_tdd; + int harq_pid = 0; dlsch->slot_tx[slot] = 1; - dlsch->harq_ids[frame%2][slot] = harq_pid; + dlsch->harq_ids[frame % 2][slot] = 0; AssertFatal(harq_pid < 8 && harq_pid >= 0, "illegal harq_pid %d\n",harq_pid); dlsch->harq_mask |= (1<rnti = pdcch_pdu_rel15->dci_pdu.RNTI[i]; + dlsch->rnti = pdcch_pdu_rel15->dci_pdu[i].RNTI; // nr_fill_cce_list(gNB,0); /* @@ -300,7 +299,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB, for (int i=0;inumDlDci;i++) { - //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i]; + //uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu[i].Payload; // if there's no DL DCI then generate CCE list // nr_fill_cce_list(gNB,0); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 4461edb33b..1cce5e1174 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -35,7 +35,9 @@ #include "nr_sch_dmrs.h" #include "PHY/MODULATION/nr_modulation.h" #include "PHY/NR_REFSIG/dmrs_nr.h" +#include "PHY/NR_REFSIG/ptrs_nr.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "LAYER2/NR_MAC_gNB/mac_proto.h" //#define DEBUG_DLSCH //#define DEBUG_DLSCH_MAPPING @@ -117,8 +119,8 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot]; int32_t** txdataF = gNB->common_vars.txdataF; int16_t amp = AMP; - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; int xOverhead = 0; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; time_stats_t *dlsch_encoding_stats=&gNB->dlsch_encoding_stats; time_stats_t *dlsch_scrambling_stats=&gNB->dlsch_scrambling_stats; time_stats_t *dlsch_modulation_stats=&gNB->dlsch_modulation_stats; @@ -134,13 +136,12 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, dlsch = gNB->dlsch[dlsch_id][0]; if (dlsch->slot_tx[slot] == 0) continue; - int harq_pid = dlsch->harq_ids[frame%2][slot]; - NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid]; + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; 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; + int8_t Wf[2], Wt[2], l0, l_prime, l_overline, delta; uint8_t dmrs_Type = rel15->dmrsConfigType; int nb_re_dmrs; uint16_t n_dmrs; @@ -152,13 +153,31 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData; n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1; } - uint16_t nb_re; - nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + + uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100 + uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos); + uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers; uint8_t Qm = rel15->qamModOrder[0]; uint32_t encoded_length = nb_re*Qm; - int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16))); - - + int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16))); + + /* PTRS */ + uint16_t beta_ptrs = 1; + uint8_t ptrs_symbol = 0; + uint16_t dlPtrsSymPos = 0; + uint16_t n_ptrs = 0; + uint16_t ptrs_idx = 0; + uint8_t is_ptrs_re = 0; + if(rel15->pduBitmap & 0x1) { + set_ptrs_symb_idx(&dlPtrsSymPos, + rel15->NrOfSymbols, + rel15->StartSymbolIndex, + 1<PTRSTimeDensity, + rel15->dlDmrsSymbPos); + n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity; + } + int16_t mod_ptrs[n_ptrs<<1] __attribute__ ((aligned(16))); + /// CRC, coding, interleaving and rate matching AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); start_meas(dlsch_encoding_stats); @@ -248,28 +267,28 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, /// 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 - + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { + if (rel15->dlDmrsSymbPos & (1 << l)) { + nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // 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"); - } + printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, 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[l][((i<<3)+j)<<1], mod_dmrs[l][(((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->rbStart*NR_NB_SC_PER_RB; + uint16_t start_sc = frame_parms->first_carrier_offset + (rel15->rbStart+rel15->BWPStart)*NR_NB_SC_PER_RB; if (start_sc >= frame_parms->ofdm_symbol_size) start_sc -= frame_parms->ofdm_symbol_size; @@ -283,55 +302,115 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, 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]; + l_prime = 0; // single symbol ap 0 + l0 = get_l0(rel15->dlDmrsSymbPos); + l_overline = l0; + #ifdef DEBUG_DLSCH_MAPPING + uint8_t dmrs_symbol = l0+l_prime; 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); + 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime, l0, dmrs_symbol); #endif - uint8_t k_prime=0; - uint16_t m=0, n=0, dmrs_idx=0, k=0; - + + uint16_t m=0, dmrs_idx=0, k=0; + 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; - + + // Loop Over OFDM symbols: for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { - k = start_sc; - 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; + /// DMRS QPSK modulation + uint8_t k_prime=0; + uint16_t n=0; + if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion + 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; + } + + // Update l_prime in the case of double DMRS config + if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion + if (l==(l_overline+1)) //take into account the double DMRS symbols + l_prime = 1; + else if (l>(l_overline+1)) {//new DMRS pair + l_overline = l; + l_prime = 0; + } + } + + /* calculate if current symbol is PTRS symbols */ + ptrs_idx = 0; + + if(rel15->pduBitmap & 0x1) { + ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos); + if(ptrs_symbol) { + /* PTRS QPSK Modulation for each OFDM symbol in a slot */ + nr_modulation(pdsch_dmrs[l][0], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs); + } + } + k = start_sc; + // Loop Over SCs: + for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { + /* check if cuurent RE is PTRS RE*/ + is_ptrs_re=0; + /* check for PTRS symbol and set flag for PTRS RE */ + if(ptrs_symbol){ + is_ptrs_re = is_ptrs_subcarrier(k, + rel15->rnti, + ap, + rel15->dmrsConfigType, + rel15->PTRSFreqDensity, + rel15->rbSize, + rel15->PTRSReOffset, + start_sc, + frame_parms->ofdm_symbol_size); + } + + /* Map DMRS Symbol */ + if ( ( dmrs_symbol_map & (1 << l) ) && (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]*Wf[k_prime]*amp*mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime]*Wf[k_prime]*amp*mod_dmrs[l][(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) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + 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++; - k_prime&=1; - n+=(k_prime)?0:1; - } - - else { - if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { - ((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; + dmrs_idx++; + k_prime++; + k_prime&=1; + n+=(k_prime)?0:1; + } + /* Map PTRS Symbol */ + else if(is_ptrs_re){ + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", - m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + printf("ptrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", + ptrs_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 - m++; - } - } - if (++k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - } //RE loop + ptrs_idx++; + } + /* Map DATA Symbol */ + else { + if( (!(dmrs_symbol_map & (1 << l))) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,frame_parms->ofdm_symbol_size,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; +#ifdef DEBUG_DLSCH_MAPPING + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", + m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); +#endif + m++; + } + } + if (++k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } //RE loop } // symbol loop }// layer loop + + dlsch->slot_tx[slot]=0; }// dlsch loop return 0; @@ -341,15 +420,8 @@ void dump_pdsch_stats(PHY_VARS_gNB *gNB) { for (int i=0;idlsch_stats[i].rnti > 0) - LOG_I(PHY,"DLSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes TX %d\n", + LOG_D(PHY,"DLSCH RNTI %x: current_Qm %d, current_RI %d, total_bytes TX %d\n", gNB->dlsch_stats[i].rnti, - gNB->dlsch_stats[i].round_trials[0], - (double)gNB->dlsch_stats[i].round_trials[1]/gNB->dlsch_stats[i].round_trials[0], - gNB->dlsch_stats[i].round_trials[1], - (double)gNB->dlsch_stats[i].round_trials[2]/gNB->dlsch_stats[i].round_trials[0], - gNB->dlsch_stats[i].round_trials[2], - (double)gNB->dlsch_stats[i].round_trials[3]/gNB->dlsch_stats[i].round_trials[0], - gNB->dlsch_stats[i].round_trials[3], gNB->dlsch_stats[i].current_Qm, gNB->dlsch_stats[i].current_RI, gNB->dlsch_stats[i].total_bytes_tx); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index 23ec756531..6af8f28eac 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -95,7 +95,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, time_stats_t *dlsch_interleaving_stats, time_stats_t *dlsch_segmentation_stats); - +void init_dlsch_tpool(uint8_t nun_dlsch_threads); void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size); void dump_pdsch_stats(PHY_VARS_gNB *gNB); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index a4a684c4e4..e6544bbe0c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -51,7 +51,6 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) { - int i; int r; NR_gNB_DLSCH_t *dlsch = *dlschptr; @@ -63,76 +62,61 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) a_segments = a_segments*N_RB; a_segments = a_segments/273 +1; } - - - + + + #ifdef DEBUG_DLSCH_FREE LOG_D(PHY,"Freeing dlsch %p\n",dlsch); #endif - - for (i=0; iMdlharq; i++) { + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; + if (harq->b) { + free16(harq->b, a_segments * 1056); + harq->b = NULL; #ifdef DEBUG_DLSCH_FREE - LOG_D(PHY,"Freeing dlsch process %d\n",i); + LOG_D(PHY, "Freeing harq->b (%p)\n", harq->b); #endif - if (dlsch->harq_processes[i]) { + if (harq->e) { + free16(harq->e, 14 * N_RB * 12 * 8); + harq->e = NULL; #ifdef DEBUG_DLSCH_FREE - LOG_D(PHY,"Freeing dlsch process %d (%p)\n",i,dlsch->harq_processes[i]); + printf("Freeing dlsch process %d e (%p)\n", i, harq->e); #endif - - if (dlsch->harq_processes[i]->b) { - free16(dlsch->harq_processes[i]->b,a_segments*1056); - 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]); -#endif - - if (dlsch->harq_processes[i]->c[r]) { - free16(dlsch->harq_processes[i]->c[r],1056); - dlsch->harq_processes[i]->c[r] = NULL; - } - if (dlsch->harq_processes[i]->d[r]) { - free16(dlsch->harq_processes[i]->d[r],3*8448); - dlsch->harq_processes[i]->d[r] = NULL; - } - - } - free16(dlsch->harq_processes[i],sizeof(NR_DL_gNB_HARQ_t)); - dlsch->harq_processes[i] = NULL; } - } - free16(dlsch,sizeof(NR_gNB_DLSCH_t)); - *dlschptr = NULL; + if (harq->f) { + free16(harq->f, 14 * N_RB * 12 * 8); + harq->f = NULL; +#ifdef DEBUG_DLSCH_FREE + printf("Freeing dlsch process %d f (%p)\n", i, harq->f); +#endif + } + +#ifdef DEBUG_DLSCH_FREE + LOG_D(PHY, "Freeing dlsch process %d c (%p)\n", i, harq->c); +#endif + + for (r = 0; r < a_segments; r++) { +#ifdef DEBUG_DLSCH_FREE + LOG_D(PHY, "Freeing dlsch process %d c[%d] (%p)\n", i, r, harq->c[r]); +#endif + + if (harq->c[r]) { + free16(harq->c[r], 1056); + harq->c[r] = NULL; + } + if (harq->d[r]) { + free16(harq->d[r], 3 * 8448); + harq->d[r] = NULL; + } + } + free16(harq, sizeof(NR_DL_gNB_HARQ_t)); + harq = NULL; + } } + free16(dlsch, sizeof(NR_gNB_DLSCH_t)); + *dlschptr = NULL; } NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, @@ -142,9 +126,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint8_t abstraction_flag, uint16_t N_RB) { - - NR_gNB_DLSCH_t *dlsch; - unsigned char exit_flag = 0,i,r,aa,layer; + unsigned char i,r,aa,layer; int re; uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated @@ -155,127 +137,74 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment + NR_gNB_DLSCH_t *dlsch = malloc16(sizeof(NR_gNB_DLSCH_t)); + AssertFatal(dlsch, "cannot allocate dlsch\n"); + + bzero(dlsch,sizeof(NR_gNB_DLSCH_t)); + dlsch->Kmimo = Kmimo; + dlsch->Mdlharq = Mdlharq; + dlsch->Mlimit = 4; + dlsch->Nsoft = Nsoft; - dlsch = (NR_gNB_DLSCH_t *)malloc16(sizeof(NR_gNB_DLSCH_t)); + for (layer=0; layerue_spec_bf_weights[layer] = (int32_t **)malloc16(64 * sizeof(int32_t *)); - if (dlsch) { - bzero(dlsch,sizeof(NR_gNB_DLSCH_t)); - dlsch->Kmimo = Kmimo; - dlsch->Mdlharq = Mdlharq; - dlsch->Mlimit = 4; - dlsch->Nsoft = Nsoft; - - for (layer=0; layerue_spec_bf_weights[layer] = (int32_t**)malloc16(64*sizeof(int32_t*)); - - 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 - } - - for (int q=0; qmod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH*sizeof(int32_t)); - - dlsch->calib_dl_ch_estimates = (int32_t**)malloc16(64*sizeof(int32_t*)); - for (aa=0; aa<64; aa++) { - dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES*sizeof(int32_t)); - - } - - for (i=0; i<20; i++) { - dlsch->harq_ids[0][i] = 0; - dlsch->harq_ids[1][i] = 0; - } - - 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 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(dlsch_bytes); - dlsch->harq_processes[i]->pdu = (uint8_t*)malloc16(dlsch_bytes); - if (dlsch->harq_processes[i]->pdu) { - 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,dlsch_bytes); - } else { - LOG_D(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); - dlsch->harq_processes[i]->d[r] = (uint8_t*)malloc16(68*384); //max size for coded output - if (dlsch->harq_processes[i]->c[r]) { - bzero(dlsch->harq_processes[i]->c[r],8448); - } else { - LOG_D(PHY,"Can't get c\n"); - exit_flag=2; - } - if (dlsch->harq_processes[i]->d[r]) { - bzero(dlsch->harq_processes[i]->d[r],(3*8448)); - } else { - LOG_D(PHY,"Can't get d\n"); - exit_flag=2; - } - } - dlsch->harq_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); - exit_flag=3; + 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; re < OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; re++) { + dlsch->ue_spec_bf_weights[layer][aa][re] = 0x00007fff; } } - if (exit_flag==0) { - for (i=0; iharq_processes[i]->round=0; - } - - return(dlsch); - } + 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 } - LOG_D(PHY,"new_gNB_dlsch exit flag %d, size of %ld\n", - exit_flag, sizeof(NR_gNB_DLSCH_t)); + for (int q = 0; q < NR_MAX_NB_CODEWORDS; q++) + dlsch->mod_symbs[q] = (int32_t *)malloc16(NR_MAX_PDSCH_ENCODED_LENGTH * sizeof(int32_t)); - free_gNB_dlsch(&dlsch,N_RB); + dlsch->calib_dl_ch_estimates = (int32_t **)malloc16(64 * sizeof(int32_t *)); + for (aa = 0; aa < 64; aa++) { + dlsch->calib_dl_ch_estimates[aa] = (int32_t *)malloc16(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES * sizeof(int32_t)); + } - return(NULL); + for (i = 0; i < 20; i++) { + dlsch->harq_ids[0][i] = 0; + dlsch->harq_ids[1][i] = 0; + } + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; + bzero(harq, sizeof(NR_DL_gNB_HARQ_t)); + harq->b = malloc16(dlsch_bytes); + AssertFatal(harq->b, "cannot allocate memory for harq->b\n"); + harq->pdu = malloc16(dlsch_bytes); + AssertFatal(harq->pdu, "cannot allocate memory for harq->pdu\n"); + bzero(harq->pdu, dlsch_bytes); + nr_emulate_dlsch_payload(harq->pdu, (dlsch_bytes) >> 3); + bzero(harq->b, dlsch_bytes); + + for (r = 0; r < a_segments; r++) { + // account for filler in first segment and CRCs for multiple segment case + // [hna] 8448 is the maximum CB size in NR + // 68*348 = 68*(maximum size of Zc) + // In section 5.3.2 in 38.212, the for loop is up to N + 2*Zc (maximum size of N is 66*Zc, therefore 68*Zc) + harq->c[r] = malloc16(8448); + AssertFatal(harq->c[r], "cannot allocate harq->c[%d]\n", r); + harq->d[r] = malloc16(68 * 384); + AssertFatal(harq->d[r], "cannot allocate harq->d[%d]\n", r); // max size for coded output + bzero(harq->c[r], 8448); + bzero(harq->d[r], (3 * 8448)); + harq->e = malloc16(14 * N_RB * 12 * 8); + AssertFatal(harq->e, "cannot allocate harq->e\n"); + bzero(harq->e, 14 * N_RB * 12 * 8); + harq->f = malloc16(14 * N_RB * 12 * 8); + AssertFatal(harq->f, "cannot allocate harq->f\n"); + bzero(harq->f, 14 * N_RB * 12 * 8); + } + + return(dlsch); } void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) @@ -284,28 +213,21 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) unsigned char Mdlharq; unsigned char i,j,r; - if (dlsch) { - Mdlharq = dlsch->Mdlharq; - dlsch->rnti = 0; - dlsch->active = 0; + AssertFatal(dlsch!=NULL,"dlsch is null\n"); + Mdlharq = dlsch->Mdlharq; + dlsch->rnti = 0; + dlsch->active = 0; + NR_DL_gNB_HARQ_t *harq=&dlsch->harq_process; - for (i=0; i<10; i++) { - dlsch->harq_ids[0][i] = Mdlharq; - dlsch->harq_ids[1][i] = Mdlharq; - } - for (i=0; iharq_processes[i]) { - // dlsch->harq_processes[i]->Ndi = 0; - //dlsch->harq_processes[i]->status = 0; - 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; - - } - } + for (i=0; i<10; i++) { + dlsch->harq_ids[0][i] = Mdlharq; + dlsch->harq_ids[1][i] = Mdlharq; + } + for (i=0; id[r]) + harq->d[r][j] = NR_NULL; } } @@ -322,18 +244,15 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, unsigned int G; unsigned int crc=1; - 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_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; uint16_t nb_rb = rel15->rbSize; uint8_t nb_symb_sch = rel15->NrOfSymbols; uint32_t A, Kb, F=0; - static uint32_t Z = 0; - uint32_t *Zc = &Z; + uint32_t *Zc = &dlsch->harq_process.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 = 1; uint32_t Tbslbrm = 950984; //max tbs @@ -349,8 +268,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, float Coderate = 0.0; uint8_t Nl = 4; - dlsch->harq_processes[harq_pid]->round = nr_rv_round_map[rel15->rvIndex[0]]; - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN); A = rel15->TBSize[0]<<3; @@ -369,174 +287,157 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, } if (stats) { - stats->round_trials[dlsch->harq_processes[harq_pid]->round]++; stats->rnti = dlsch->rnti; - if (dlsch->harq_processes[harq_pid]->round == 0){ - stats->total_bytes_tx += rel15->TBSize[0]; - stats->current_RI = rel15->nrOfLayers; - stats->current_Qm = rel15->qamModOrder[0]; - } + stats->total_bytes_tx += rel15->TBSize[0]; + stats->current_RI = rel15->nrOfLayers; + stats->current_Qm = rel15->qamModOrder[0]; } 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); - // 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\n",a[i]); - LOG_D(PHY,"\n"); - */ + 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)]); + + harq->B = A+24; + // harq->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_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); // 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); - - 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; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) - BG = 2; - 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 - uint16_t Kr_bytes; - Kr_bytes = Kr>>3; -#endif - - //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]; - //channel_input[r] = &dlsch->harq_processes[harq_pid]->d[r][0]; -#ifdef DEBUG_DLSCH_CODING - 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*(*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],*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); - } - encoder_implemparams_t impp; - impp.n_segments=dlsch->harq_processes[harq_pid]->C; - impp.tprep = tprep; - impp.tinput = tinput; - impp.tparity = tparity; - impp.toutput = toutput; - - for(int j=0;j<(dlsch->harq_processes[harq_pid]->C/8+1);j++) { - impp.macro_num=j; - nrLDPC_encoder(dlsch->harq_processes[harq_pid]->c,dlsch->harq_processes[harq_pid]->d,*Zc,Kb,Kr,BG,&impp); - } - - -#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); -#endif + 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(harq->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)]); + + harq->B = A+16; + // harq->b = a; - F = dlsch->harq_processes[harq_pid]->F; + 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); - Kr = dlsch->harq_processes[harq_pid]->K; - for (r=0; rharq_processes[harq_pid]->C; r++) { + memcpy(harq->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; + + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) + harq->BG = 2; + else + harq->BG = 1; + + start_meas(dlsch_segmentation_stats); + Kb = nr_segmentation(harq->b, harq->c, harq->B, &harq->C, &harq->K, Zc, &harq->F, harq->BG); + stop_meas(dlsch_segmentation_stats); + F = harq->F; + + Kr = harq->K; +#ifdef DEBUG_DLSCH_CODING + uint16_t Kr_bytes; + Kr_bytes = Kr>>3; +#endif + //printf("segment Z %d k %d Kr %d BG %d C %d\n", *Zc,harq->K,Kr,BG,harq->C); + + for (r=0; rC; r++) { + //d_tmp[r] = &harq->d[r][0]; + //channel_input[r] = &harq->d[r][0]; +#ifdef DEBUG_DLSCH_CODING + LOG_D(PHY,"Encoder: B %d F %d \n",harq->B, harq->F); + LOG_D(PHY,"start ldpc encoder segment %d/%d\n",r,harq->C); + LOG_D(PHY,"input %d %d %d %d %d \n", harq->c[r][0], harq->c[r][1], harq->c[r][2],harq->c[r][3], harq->c[r][4]); + for (int cnt =0 ; cnt < 22*(*Zc)/8; cnt ++){ + LOG_D(PHY,"%d ", harq->c[r][cnt]); + } + LOG_D(PHY,"\n"); + +#endif + //ldpc_encoder_orig((unsigned char*)harq->c[r],harq->d[r],*Zc,Kb,Kr,BG,0); + //ldpc_encoder_optim((unsigned char*)harq->c[r],(unsigned char*)&harq->d[r][0],*Zc,Kb,Kr,BG,NULL,NULL,NULL,NULL); + } + encoder_implemparams_t impp; + impp.n_segments=harq->C; + impp.tprep = tprep; + impp.tinput = tinput; + impp.tparity = tparity; + impp.toutput = toutput; + + for(int j=0;j<(harq->C/8+1);j++) { + impp.macro_num=j; + nrLDPC_encoder(harq->c,harq->d,*Zc,Kb,Kr,harq->BG,&impp); + } + + +#ifdef DEBUG_DLSCH_CODING + write_output("enc_input0.m","enc_in0",&harq->c[0][0],Kr_bytes,1,4); + write_output("enc_output0.m","enc0",&harq->d[0][0],(3*8*Kr_bytes)+12,1,4); +#endif + + F = harq->F; + + Kr = harq->K; + for (r=0; rC; r++) { + if (F>0) { for (int k=(Kr-F-2*(*Zc)); kharq_processes[harq_pid]->d[r][k] = NR_NULL; + harq->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]); + //printf("r %d filler bits [%d] = %d \n", r,k, harq->d[r][k]); } } - - - + + + #ifdef DEBUG_DLSCH_CODING - LOG_D(PHY,"rvidx in encoding = %d\n", rel15->rvIndex[0]); + 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->nrOfLayers, r); - + + E = nr_get_E(G, harq->C, mod_order, rel15->nrOfLayers, r); + //#ifdef DEBUG_DLSCH_CODING LOG_D(PHY,"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, + harq->C, G, E, F, Kr-F-2*(*Zc), mod_order,nb_rb); - + // 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); - + start_meas(dlsch_rate_matching_stats); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, - BG, + harq->BG, *Zc, - dlsch->harq_processes[harq_pid]->d[r], - dlsch->harq_processes[harq_pid]->e+r_offset, - dlsch->harq_processes[harq_pid]->C, + harq->d[r], + harq->e+r_offset, + harq->C, F, Kr-F-2*(*Zc), rel15->rvIndex[0], @@ -544,22 +445,22 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, stop_meas(dlsch_rate_matching_stats); #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) - printf("output ratematching e[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->e[i+r_offset], r_offset); + printf("output ratematching e[%d]= %d r_offset %u\n", i,harq->e[i+r_offset], r_offset); #endif 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); + harq->e+r_offset, + harq->f+r_offset); stop_meas(dlsch_interleaving_stats); #ifdef DEBUG_DLSCH_CODING for (int i =0; i<16; i++) - printf("output interleaving f[%d]= %d r_offset %u\n", i,dlsch->harq_processes[harq_pid]->f[i+r_offset], r_offset); + printf("output interleaving f[%d]= %d r_offset %u\n", i,harq->f[i+r_offset], r_offset); - if (r==dlsch->harq_processes[harq_pid]->C-1) - write_output("enc_output.m","enc",dlsch->harq_processes[harq_pid]->f,G,1,4); + if (r==harq->C-1) + write_output("enc_output.m","enc",harq->f,G,1,4); #endif r_offset += E; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 5ce2c45a7d..05d6c4c112 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -289,12 +289,12 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, AssertFatal( (dlsch_id>=0) && (dlsch_idrnti,dlsch_id); NR_gNB_DLSCH_t *dlsch = gNB->dlsch[dlsch_id][0]; - NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes; + NR_DL_gNB_HARQ_t *harq = &dlsch->harq_process; /// DLSCH struct - memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + memcpy((void*)&harq->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu)); gNB->num_pdsch_rnti[slot]++; AssertFatal(sdu!=NULL,"sdu is null\n"); - harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu; + harq->pdu = sdu; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index e263c2c2cc..b5a3c061e9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -37,31 +37,42 @@ extern uint16_t prach_root_sequence_map_0_3[838]; extern uint16_t prach_root_sequence_map_abc[138]; extern uint16_t nr_du[838]; -extern const char *prachfmt[9]; +extern const char *prachfmt[]; void init_prach_list(PHY_VARS_gNB *gNB) { AssertFatal(gNB!=NULL,"gNB is null\n"); - for (int i=0; iprach_vars.list[i].frame=-1; + for (int i=0; iprach_vars.list[i].frame = -1; + gNB->prach_vars.list[i].slot = -1; + } } -int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type) { +void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id) { - uint16_t i; - int16_t first_free_index=-1; + gNB->prach_vars.list[prach_id].frame = -1; + gNB->prach_vars.list[prach_id].slot = -1; + +} + +int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame, int slot, find_type_t type) { AssertFatal(gNB!=NULL,"gNB is null\n"); - for (i=0; i %d.%d numRA %d\n", frame,slot,numRA,i, - gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot,gNB->prach_vars.list[i].pdu.num_ra); - if ((gNB->prach_vars.list[i].frame == frame) && - (gNB->prach_vars.list[i].slot == slot) && - (gNB->prach_vars.list[i].pdu.num_ra == numRA)) return i; - else if ((gNB->prach_vars.list[i].frame == -1) && (first_free_index==-1)) first_free_index=i; + for (uint16_t i=0; i %d.%d\n", frame,slot,i, + gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot); + if((type == SEARCH_EXIST_OR_FREE) && + (gNB->prach_vars.list[i].frame == -1) && + (gNB->prach_vars.list[i].slot == -1)) { + return i; + } + else if ((type == SEARCH_EXIST) && + (gNB->prach_vars.list[i].frame == frame) && + (gNB->prach_vars.list[i].slot == slot)) { + return i; + } } - if (type == SEARCH_EXIST) return -1; - - return first_free_index; + return -1; } void nr_fill_prach(PHY_VARS_gNB *gNB, @@ -69,9 +80,9 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int Slot, nfapi_nr_prach_pdu_t *prach_pdu) { - int prach_id = find_nr_prach(gNB,SFN,Slot,prach_pdu->num_ra,SEARCH_EXIST_OR_FREE); - AssertFatal( (prach_id>=0) && (prach_idnum_ra,prach_id); + int prach_id = find_nr_prach(gNB,SFN,Slot,SEARCH_EXIST_OR_FREE); + AssertFatal( ((prach_id>=0) && (prach_idprach_vars.list[prach_id].frame=SFN; gNB->prach_vars.list[prach_id].slot=Slot; @@ -82,31 +93,35 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, void init_prach_ru_list(RU_t *ru) { AssertFatal(ru!=NULL,"ruis null\n"); - for (int i=0; iprach_list[i].frame=-1; + for (int i=0; iprach_list[i].frame = -1; + ru->prach_list[i].slot = -1; + } pthread_mutex_init(&ru->prach_list_mutex,NULL); } int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) { - uint16_t i; - int16_t first_free_index=-1; - AssertFatal(ru!=NULL,"ru is null\n"); pthread_mutex_lock(&ru->prach_list_mutex); - for (i=0; i %d.%d\n", frame,slot,i, ru->prach_list[i].frame,ru->prach_list[i].slot); - if ((ru->prach_list[i].frame == frame) && - (ru->prach_list[i].slot == slot)) { + if((type == SEARCH_EXIST_OR_FREE) && + (ru->prach_list[i].frame == -1) && + (ru->prach_list[i].slot == -1)) { + pthread_mutex_unlock(&ru->prach_list_mutex); + return i; + } + else if ((type == SEARCH_EXIST) && + (ru->prach_list[i].frame == frame) && + (ru->prach_list[i].slot == slot)) { pthread_mutex_unlock(&ru->prach_list_mutex); return i; } - else if ((ru->prach_list[i].frame == -1) && (first_free_index==-1)) first_free_index=i; } pthread_mutex_unlock(&ru->prach_list_mutex); - if (type == SEARCH_EXIST) return -1; - - return first_free_index; + return -1; } void nr_fill_prach_ru(RU_t *ru, @@ -115,7 +130,7 @@ void nr_fill_prach_ru(RU_t *ru, nfapi_nr_prach_pdu_t *prach_pdu) { int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE); - AssertFatal( (prach_id>=0) && (prach_id=0) && (prach_idprach_list_mutex); @@ -124,6 +139,7 @@ void nr_fill_prach_ru(RU_t *ru, ru->prach_list[prach_id].fmt = prach_pdu->prach_format; ru->prach_list[prach_id].numRA = prach_pdu->num_ra; ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol; + ru->prach_list[prach_id].num_prach_ocas = prach_pdu->num_prach_ocas; pthread_mutex_unlock(&ru->prach_list_mutex); } @@ -132,7 +148,8 @@ void free_nr_ru_prach_entry(RU_t *ru, int prach_id) { pthread_mutex_lock(&ru->prach_list_mutex); - ru->prach_list[prach_id].frame=-1; + ru->prach_list[prach_id].frame = -1; + ru->prach_list[prach_id].slot = -1; pthread_mutex_unlock(&ru->prach_list_mutex); } @@ -142,6 +159,7 @@ void rx_nr_prach_ru(RU_t *ru, int prachFormat, int numRA, int prachStartSymbol, + int prachOccasion, int frame, int slot) { @@ -156,15 +174,21 @@ void rx_nr_prach_ru(RU_t *ru, int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; - rxsigF = ru->prach_rxsigF; + int sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + //to be checked for mu=0; + + LOG_D(PHY,"frame %d, slot %d: doing rx_nr_prach_ru for format %d, numRA %d, prachStartSymbol %d, prachOccasion %d\n",frame,slot,prachFormat,numRA,prachStartSymbol,prachOccasion); + + rxsigF = ru->prach_rxsigF[prachOccasion]; AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n"); for (int aa=0; aanb_rx; aa++){ if (prach_sequence_length == 0) slot2=(slot/fp->slots_per_subframe)*fp->slots_per_subframe; - prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot2*fp->get_samples_per_slot(slot,fp))-ru->N_TA_offset]; + prach[aa] = (int16_t*)&ru->common.rxdata[aa][fp->get_samples_slot_timestamp(slot2,fp,0)+sample_offset_slot-ru->N_TA_offset]; } + idft_size_idx_t dftsize; int dftlen=0; int mu = fp->numerology_index; int Ncp = 0; @@ -198,22 +222,24 @@ void rx_nr_prach_ru(RU_t *ru, ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol); switch (prachFormat) { - case 0: //A1 + case 4: //A1 Ncp = 288/(1<nb_rx, Ncp); } - AssertFatal(mu==1,"only 30 kHz SCS handled for now\n"); + + // Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below int kbar = 1; @@ -265,13 +292,15 @@ void rx_nr_prach_ru(RU_t *ru, if (k<0) k+=(fp->ofdm_symbol_size); k*=K; - k+=kbar; + k+=kbar; + int reps=1; for (int aa=0; aanb_rx; aa++) { AssertFatal(prach[aa]!=NULL,"prach[%d] is null\n",aa); // do DFT + if (mu==1) { if (fp->N_RB_UL <= 100) AssertFatal(1==0,"N_RB_UL %d not support for NR PRACH yet\n",fp->N_RB_UL); else if (fp->N_RB_UL < 137) { @@ -300,36 +329,29 @@ void rx_nr_prach_ru(RU_t *ru, } }// 839 sequence else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (prachStartSymbol == 0) + prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=2048; - dft(DFT_2048,prach2,rxsigF[aa],1); - if (prachFormat != 7) { // !=C0 - dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); - reps++; - } - if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { - dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); - dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); - reps+=2; - } - if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { - dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); - dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); - reps+=2; - } - if (prachFormat == 6) { - for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); - reps+=6; - } + dftlen=2048; + dft(DFT_2048,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_2048,prach2+4096,rxsigF[aa]+4096,1); + reps++; + } + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_2048,prach2+4096*2,rxsigF[aa]+4096*2,1); + dft(DFT_2048,prach2+4096*3,rxsigF[aa]+4096*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_2048,prach2+4096*4,rxsigF[aa]+4096*4,1); + dft(DFT_2048,prach2+4096*5,rxsigF[aa]+4096*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_2048,prach2+(4096*i),rxsigF[aa]+(4096*i),1); + reps+=6; } - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } else { // threequarter sampling // 40 MHz @ 46.08 Ms/s @@ -356,36 +378,28 @@ void rx_nr_prach_ru(RU_t *ru, reps=4; } } else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=1536; - dft(DFT_1536,prach2,rxsigF[aa],1); - if (prachFormat != 7) { - dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); - reps++; - } - - if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { - dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); - dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); - reps+=2; - } - if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { - dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); - dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); - reps+=2; - } - if (prachFormat == 6) { - for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); - reps+=6; - } - }// mu==1 - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); + if (prachStartSymbol == 0) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) + dftlen=1536; + dft(DFT_1536,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_1536,prach2+3072,rxsigF[aa]+3072,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_1536,prach2+3072*2,rxsigF[aa]+3072*2,1); + dft(DFT_1536,prach2+3072*3,rxsigF[aa]+3072*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_1536,prach2+3072*4,rxsigF[aa]+3072*4,1); + dft(DFT_1536,prach2+3072*5,rxsigF[aa]+3072*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_1536,prach2+(3072*i),rxsigF[aa]+(3072*i),1); + reps+=6; + } } // short format } // 3/4 sampling } // <=50 MHz BW @@ -415,37 +429,29 @@ void rx_nr_prach_ru(RU_t *ru, } } else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (prachStartSymbol == 0) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=4096; - dft(DFT_4096,prach2,rxsigF[aa],1); - if (prachFormat != 7) { //!=C0 - dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); - reps++; - } - - if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { - dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); - dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); - reps+=2; - } - if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { - dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); - dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); - reps+=2; - } - if (prachFormat == 6) { - for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1); - reps+=6; - } + dftlen=4096; + dft(DFT_4096,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_4096,prach2+8192,rxsigF[aa]+8192,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_4096,prach2+8192*2,rxsigF[aa]+8192*2,1); + dft(DFT_4096,prach2+8192*3,rxsigF[aa]+8192*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_4096,prach2+8192*4,rxsigF[aa]+8192*4,1); + dft(DFT_4096,prach2+8192*5,rxsigF[aa]+8192*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_4096,prach2+(8192*i),rxsigF[aa]+(8192*i),1); + reps+=6; } - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } else { AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n"); @@ -467,40 +473,85 @@ void rx_nr_prach_ru(RU_t *ru, reps=4; } } else { - if ((mu==0 && - (prachStartSymbol == 0 || prachStartSymbol == 7)) || - (mu==1 && prachStartSymbol == 0)) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (prachStartSymbol == 0) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) - if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==1) { - dftlen=3072; - dft(DFT_3072,prach2,rxsigF[aa],1); - if (prachFormat != 7) { //!=C0 - dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); - reps++; - } - - if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { - dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); - dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); - reps+=2; - } - if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { - dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); - dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); - reps+=2; - } - if (prachFormat == 6) { - for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); - reps+=6; - } + dftlen=3072; + dft(DFT_3072,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(DFT_3072,prach2+6144,rxsigF[aa]+6144,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(DFT_3072,prach2+6144*2,rxsigF[aa]+6144*2,1); + dft(DFT_3072,prach2+6144*3,rxsigF[aa]+6144*3,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(DFT_3072,prach2+6144*4,rxsigF[aa]+6144*4,1); + dft(DFT_3072,prach2+6144*5,rxsigF[aa]+6144*5,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) dft(DFT_3072,prach2+(6144*i),rxsigF[aa]+(6144*i),1); + reps+=6; } - else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); - else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } } + } + else if (mu==3) { + if (fp->threequarter_fs) { + AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); + } + if (prach_sequence_length == 0) { + AssertFatal(1==0,"long prach not supported for numerology %d\n",mu); + } + if (fp->N_RB_UL == 32) { + prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 for 61.44Msps + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe + dftlen=512; + dftsize = DFT_512; + } + else if (fp->N_RB_UL == 66) { + prach2 = prach[aa] + (Ncp<<3); // Ncp is for 30.72 Ms/s, so multiply by 4 for I/Q, and 2 for 122.88Msps + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe + dftlen=1024; + dftsize = DFT_1024; + } + else { + AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); + } + + dft(dftsize,prach2,rxsigF[aa],1); + if (prachFormat != 9/*C0*/) { + dft(dftsize,prach2+dftlen*2,rxsigF[aa]+dftlen*2,1); + reps++; + } + + if (prachFormat == 5/*A2*/ || prachFormat == 6/*A3*/|| prachFormat == 8/*B4*/ || prachFormat == 10/*C2*/) { + dft(dftsize,prach2+dftlen*4,rxsigF[aa]+dftlen*4,1); + dft(dftsize,prach2+dftlen*6,rxsigF[aa]+dftlen*6,1); + reps+=2; + } + if (prachFormat == 6/*A3*/ || prachFormat == 8/*B4*/) { + dft(dftsize,prach2+dftlen*8,rxsigF[aa]+dftlen*8,1); + dft(dftsize,prach2+dftlen*10,rxsigF[aa]+dftlen*10,1); + reps+=2; + } + if (prachFormat == 8/*B4*/) { + for (int i=6;i<12;i++) + dft(dftsize,prach2+(dftlen*2*i),rxsigF[aa]+(dftlen*2*i),1); + reps+=6; + } + } + else { + AssertFatal(1==0,"Numerology not supported\n"); + } + + //LOG_M("ru_rxsigF_tmp.m","rxsFtmp", rxsigF[aa], dftlen*2*reps, 1, 1); //Coherent combining of PRACH repetitions (assumes channel does not change, to be revisted for "long" PRACH) LOG_D(PHY,"Doing PRACH combining of %d reptitions N_ZC %d\n",reps,N_ZC); @@ -515,13 +566,13 @@ void rx_nr_prach_ru(RU_t *ru, for (int i=1;iframe_parms; nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value; - - rootSequenceIndex = cfg->num_prach_fd_occasions_list[0].prach_root_sequence_index.value; - numrootSequenceIndex = cfg->num_prach_fd_occasions_list[0].num_root_sequences.value; + rootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].prach_root_sequence_index.value; + numrootSequenceIndex = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].num_root_sequences.value; NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value; int prach_sequence_length = cfg->prach_sequence_length.value; - - int msg1_frequencystart = cfg->num_prach_fd_occasions_list[0].k1.value; + int msg1_frequencystart = cfg->num_prach_fd_occasions_list[prach_pdu->num_ra].k1.value; // int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value; // cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list @@ -585,7 +634,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, uint8_t prach_fmt = prach_pdu->prach_format; uint16_t N_ZC = (prach_sequence_length==0)?839:139; - LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d \n", rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC); + LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d, format %d \n",rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC,prach_fmt); prach_ifft = gNB->prach_vars.prach_ifft; prachF = gNB->prach_vars.prachF; diff --git a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c index 04045380eb..e6a9b8c5dc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_sch_dmrs.c @@ -67,12 +67,12 @@ void get_antenna_ports(uint8_t *ap, uint8_t n_symbs, uint8_t config) { void get_Wt(int8_t *Wt, uint8_t ap, uint8_t config) { for (int i=0; i<2; i++) - *(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]); + *(Wt+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]); } void get_Wf(int8_t *Wf, uint8_t ap, uint8_t config) { for (int i=0; i<2; i++) - *(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][5+i]):(pdsch_dmrs_2[ap][5+i]); + *(Wf+i)=(config==NFAPI_NR_DMRS_TYPE1)?(pdsch_dmrs_1[ap][3+i]):(pdsch_dmrs_2[ap][3+i]); } uint8_t get_delta(uint8_t ap, uint8_t config) { diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h index a30c529459..be3ba00989 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_common_proto.h @@ -44,7 +44,7 @@ void nr_group_sequence_hopping(pucch_GroupHopping_t PUCCH_GroupHopping, uint32_t n_id, uint8_t n_hop, - int nr_tti_tx, + int nr_slot_tx, uint8_t *u, uint8_t *v); @@ -53,7 +53,7 @@ double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t mcs, uint8_t lnormal, uint8_t lprime, - int nr_tti_tx); + int nr_slot_tx); /** \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 d027ae2bb5..cc48c1e4bf 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -212,7 +212,7 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, \param z Pointer to input in frequnecy domain, and it is also the output in time domain \param Msc_PUSCH number of allocated data subcarriers */ -void nr_idft(uint32_t *z, uint32_t Msc_PUSCH); +void nr_idft(int32_t *z, uint32_t Msc_PUSCH); /** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms. @param rxdataF_comp Compensated channel output @@ -288,6 +288,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, void rx_nr_prach(PHY_VARS_gNB *gNB, nfapi_nr_prach_pdu_t *prach_pdu, + int prachOccasion, int frame, int subframe, uint16_t *max_preamble, @@ -298,6 +299,7 @@ void rx_nr_prach_ru(RU_t *ru, int prach_fmt, int numRA, int prachStartSymbol, + int prachOccasion, int frame, int subframe); @@ -306,7 +308,7 @@ void nr_fill_prach_ru(RU_t *ru, int Slot, nfapi_nr_prach_pdu_t *prach_pdu); -int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type); +int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type); int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type); NR_gNB_PUCCH_t *new_gNB_pucch(void); @@ -332,6 +334,8 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB, uint16_t cell_id, int slot); +void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id); + void nr_decode_pucch1(int32_t **rxdataF, pucch_GroupHopping_t pucch_GroupHopping, uint32_t n_id, // hoppingID higher layer parameter diff --git a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c index 2b0cbe72b3..4d286bc937 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_uci_tools_common.c @@ -33,11 +33,11 @@ #include "nr_dci.h" void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, - uint32_t n_id, - uint8_t n_hop, - int nr_tti_tx, - uint8_t *u, - uint8_t *v) { + uint32_t n_id, + uint8_t n_hop, + int nr_slot_tx, + uint8_t *u, + uint8_t *v) { /* * Implements TS 38.211 subclause 6.3.2.2.1 Group and sequence hopping * The following variables are set by higher layers: @@ -65,7 +65,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, *v=0; uint32_t c_init = 0; uint32_t x1,s; // TS 38.211 Subclause 5.2.1 - int l = 32, minShift = ((2*nr_tti_tx+n_hop)<<3); + int l = 32, minShift = ((2*nr_slot_tx+n_hop)<<3); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_group_sequence_hopping] calculating u,v -> "); @@ -92,7 +92,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, f_gh = f_gh%30; f_ss = n_id%30; /* for (int m=0; m<8; m++){ - f_gh = f_gh + ((1<>(8*(2*nr_tti_tx+n_hop)+m))&1))); // Not sure we have to use nr_tti_tx FIXME!!! + f_gh = f_gh + ((1<>(8*(2*nr_slot_tx+n_hop)+m))&1))); // Not sure we have to use nr_slot_tx FIXME!!! } f_gh = f_gh%30; f_ss = n_id%30;*/ @@ -102,7 +102,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, c_init = (1<<5)*floor(n_id/30)+(n_id%30); // we initialize c_init to calculate u,v s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 f_ss = n_id%30; - l = 32, minShift = (2*nr_tti_tx+n_hop); + l = 32, minShift = (2*nr_slot_tx+n_hop); while(minShift >= l) { s = lte_gold_generic(&x1, &c_init, 0); @@ -111,7 +111,7 @@ void nr_group_sequence_hopping (pucch_GroupHopping_t PUCCH_GroupHopping, tmpShift = (minShift&((1<<5)-1)); //minShift%32; *v = (uint8_t)((s>>tmpShift)&1); - // *v = (uint8_t)((s>>(2*nr_tti_tx+n_hop))&1); // Not sure we have to use nr_tti_tx FIXME!!! + // *v = (uint8_t)((s>>(2*nr_slot_tx+n_hop))&1); // Not sure we have to use nr_slot_tx FIXME!!! } *u = (f_gh+f_ss)%30; @@ -125,7 +125,7 @@ double nr_cyclic_shift_hopping(uint32_t n_id, uint8_t mcs, uint8_t lnormal, uint8_t lprime, - int nr_tti_tx) { + int nr_slot_tx) { /* * Implements TS 38.211 subclause 6.3.2.2.2 Cyclic shift hopping * - n_id: higher-layer parameter hoppingId @@ -140,7 +140,7 @@ double nr_cyclic_shift_hopping(uint32_t n_id, uint32_t x1,s = lte_gold_generic(&x1, &c_init, 1); // TS 38.211 Subclause 5.2.1 uint8_t n_cs=0; - int l = 32, minShift = (14*8*nr_tti_tx )+ 8*(lnormal+lprime); + int l = 32, minShift = (14*8*nr_slot_tx )+ 8*(lnormal+lprime); int tmpShift =0; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_cyclic_shift_hopping] calculating alpha (cyclic shift) using c_init=%u -> \n",c_init); @@ -155,8 +155,8 @@ double nr_cyclic_shift_hopping(uint32_t n_id, tmpShift = (minShift&((1<<5)-1)); //minShift%32; minShift ++; n_cs = n_cs+((1<>tmpShift)&1))); - // calculating n_cs (Not sure we have to use nr_tti_tx FIXME!!!) - // n_cs = n_cs+((1<>((14*8*nr_tti_tx) + 8*(lnormal+lprime) + m))&1))); + // calculating n_cs (Not sure we have to use nr_slot_tx FIXME!!!) + // n_cs = n_cs+((1<>((14*8*nr_slot_tx) + 8*(lnormal+lprime) + m))&1))); } alpha = (alpha * (double)((m0+mcs+n_cs)%12)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 42f88d16f4..d990176d79 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -292,7 +292,7 @@ void nr_processULSegment(void* arg) { int no_iteration_ldpc; int Kr; int Kr_bytes; - int K_bytes_F; + int K_bits_F; uint8_t crc_type; int i; int j; @@ -318,8 +318,7 @@ void nr_processULSegment(void* arg) { Kr = ulsch_harq->K; Kr_bytes = Kr>>3; - - K_bytes_F = Kr_bytes-(ulsch_harq->F>>3); + K_bits_F = Kr-ulsch_harq->F; t_nrLDPC_time_stats procTime; t_nrLDPC_time_stats* p_procTime = &procTime ; @@ -402,23 +401,19 @@ void nr_processULSegment(void* arg) { //start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); - memset(pv,0,2*ulsch_harq->Z*sizeof(int16_t)); - memset((pv+K_bytes_F),127,ulsch_harq->F*sizeof(int16_t)); - - for (i=((2*p_decoderParms->Z)>>3), j = 0; i < K_bytes_F; i++, j++) { - pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j])); - } - - AssertFatal(kc!=255,""); - j+=(ulsch_harq->F>>3); - for (i=Kr_bytes; i < ((kc*p_decoderParms->Z)>>3); i++, j++) { - pv[i]= _mm_loadu_si128((__m128i*)(&ulsch_harq->d[r][8*j])); - } - - for (i=0, j=0; j < ((kc*p_decoderParms->Z)>>4); i+=2, j++) { + //set first 2*Z_c bits to zeros + memset(&z[0],0,2*ulsch_harq->Z*sizeof(int16_t)); + //set Filler bits + memset((&z[0]+K_bits_F),127,ulsch_harq->F*sizeof(int16_t)); + //Move coded bits before filler bits + memcpy((&z[0]+2*ulsch_harq->Z),ulsch_harq->d[r],(K_bits_F-2*ulsch_harq->Z)*sizeof(int16_t)); + //skip filler bits + memcpy((&z[0]+Kr),ulsch_harq->d[r]+(Kr-2*ulsch_harq->Z),(kc*ulsch_harq->Z-Kr)*sizeof(int16_t)); + //Saturate coded bits before decoding into 8 bits values + for (i=0, j=0; j < ((kc*ulsch_harq->Z)>>4)+1; i+=2, j++) + { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } - ////////////////////////////////////////////////////////////////////////////////////////// @@ -478,7 +473,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; - + + if (!harq_process) { + LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n"); + return 1; + } + t_nrLDPC_dec_params decParams; t_nrLDPC_dec_params* p_decParams = &decParams; @@ -488,11 +488,6 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, phy_vars_gNB->nbDecode = 0; harq_process->processedSegments = 0; - if (!harq_process) { - LOG_E(PHY,"ulsch_decoding.c: NULL harq_process pointer\n"); - return 1; - } - double Coderate = 0.0; // ------------------------------------------------------------------ @@ -523,31 +518,27 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ p_decParams->BG = 2; + kc = 52; if (Coderate < 0.3333) { p_decParams->R = 15; - kc = 52; } else if (Coderate <0.6667) { p_decParams->R = 13; - kc = 32; } else { p_decParams->R = 23; - kc = 17; } } else { p_decParams->BG = 1; + kc = 68; if (Coderate < 0.6667) { p_decParams->R = 13; - kc = 68; } else if (Coderate <0.8889) { p_decParams->R = 23; - kc = 35; } else { p_decParams->R = 89; - kc = 27; } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 4622c31db3..7e6becb4a8 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -12,7 +12,7 @@ //#define DEBUG_RB_EXT //#define DEBUG_CH_MAG -void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) +void nr_idft(int32_t *z, uint32_t Msc_PUSCH) { #if defined(__x86_64__) || defined(__i386__) @@ -38,7 +38,7 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) } for (i=0,ip=0; ipusch_vars[ulsch_id]->dmrs_symbol = symbol; + } else { nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; } @@ -1219,9 +1220,21 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, symbol, rel15_ul->rb_size); stop_meas(&gNB->ulsch_mrc_stats); -#ifdef NR_SC_FDMA - nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch); -#endif + + + if (rel15_ul->transform_precoding == transform_precoder_enabled) { + + #ifdef __AVX2__ + // For odd number of resource blocks need byte alignment to multiple of 8 + int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7); + #else + int nb_re_pusch2 = nb_re_pusch; + #endif + + // perform IDFT operation on the compensated rxdata if transform precoding is enabled + nr_idft(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * nb_re_pusch2], nb_re_pusch); + LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d\n", symbol, nb_re_pusch); + } //---------------------------------------------------------- @@ -1234,43 +1247,44 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, { start_meas(&gNB->ulsch_ptrs_processing_stats); nr_pusch_ptrs_processing(gNB, + frame_parms, rel15_ul, ulsch_id, nr_tti_rx, - dmrs_symbol_flag, symbol, nb_re_pusch); stop_meas(&gNB->ulsch_ptrs_processing_stats); /* Subtract total PTRS RE's in the symbol from PUSCH RE's */ - gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol; + gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot; } - - /*---------------------------------------------------------------------------------------------------- */ - /*-------------------- LLRs computation -------------------------------------------------------------*/ - /*-----------------------------------------------------------------------------------------------------*/ - if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1)) - { -#ifdef __AVX2__ - int off = ((rel15_ul->rb_size&1) == 1)? 4:0; -#else - int off = 0; -#endif - uint32_t rxdataF_ext_offset = 0; - for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) { - start_meas(&gNB->ulsch_llr_stats); - nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], - gNB->pusch_vars[ulsch_id]->ul_ch_mag0, - gNB->pusch_vars[ulsch_id]->ul_ch_magb0, - &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order], - rel15_ul->rb_size, - gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i], - i, - rel15_ul->qam_mod_order); - stop_meas(&gNB->ulsch_llr_stats); - rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i]; - }// symbol loop - }// last symbol check } + + /*---------------------------------------------------------------------------------------------------- */ + /*-------------------- LLRs computation -------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------------------------*/ + if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1)) { + +#ifdef __AVX2__ + int off = ((rel15_ul->rb_size&1) == 1)? 4:0; +#else + int off = 0; +#endif + uint32_t rxdataF_ext_offset = 0; + for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) { + start_meas(&gNB->ulsch_llr_stats); + nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)], + gNB->pusch_vars[ulsch_id]->ul_ch_mag0, + gNB->pusch_vars[ulsch_id]->ul_ch_magb0, + &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order], + rel15_ul->rb_size, + gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i], + i, + rel15_ul->qam_mod_order); + stop_meas(&gNB->ulsch_llr_stats); + rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i]; + }// symbol loop + }// last symbol check + return (0); } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index cdad497bf1..f93bd73b14 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -394,6 +394,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, // first bit of bitmap for sr presence and second bit for acknack presence uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1); uci_pdu->pucch_format = 0; // format 0 + uci_pdu->rnti = pucch_pdu->rnti; uci_pdu->ul_cqi = cqi; uci_pdu->timing_advance = 0xffff; // currently not valid uci_pdu->rssi = 1280 - (10*dB_fixed(32767*32767)-dB_fixed_times10(signal_energy_nodc(&rxdataF[0][pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size+re_offset],12))); @@ -1464,7 +1465,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, cw_ML=cw; } } // cw loop - corr_dB = dB_fixed64(corr); + corr_dB = dB_fixed64((uint64_t)corr); LOG_D(PHY,"cw_ML %d, metric %d dB\n",cw_ML,corr_dB); decodedPayload[0]=(uint64_t)cw_ML; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c index dec3d7cc2d..990f3101fd 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c @@ -185,3 +185,57 @@ short filt8_rr1[8] = { short filt8_rr2[8] = { -4096,-8192,-12288,-16384,0,0,0,0}; + +short filt8_l2[8] = { +0,0,13107,9830,6554,3277,0,0}; + +short filt8_r2[8] = { +0,0,3277,6554,9830,13107,0,0}; + +short filt8_m2[8] = { +0,0,0,0,13107,9830,6554,3277}; + +short filt8_mm2[8]= { +0,0,0,0,3277,6554,9830,13107}; + +short filt8_rl2[8] = { +19661,22938,26214,29491,0,0,0,0}; + +short filt8_rm2[8] = { +-3277,-6554,-9830,-13107,0,0,0,0};//-3277,-6554,-9830,-13107 + +short filt8_l3[8] = { +22938,19661,0,0,13107,9830,6554,3277}; + +short filt8_r3[8] = { +-7537,-4260,0,0,3277,6554,9830,13107};//-6554,-3277 + +short filt8_rl3[8] = { +0,0,19661,22938,0,0,0,0}; + +short filt8_rr3[8] = { +0,0,-4260,-7537,0,0,0,0};//-3277,-6554 + +short filt8_dcrl1[8] = { +14895,13405,11916,10426,8937,7447,5958,4468}; + +short filt8_dcrh1[8] = { +2979,1489,0,0,0,0,0,0}; + +short filt8_dcll1[8] = { +13405,14895,0,0,0,0,0,0}; + +short filt8_dclh1[8] = { +1489,2979,4468,5958,7447,8937,10426,11916}; + +short filt8_dcrl2[8] = { +0,0,0,0,14895,13405,11916,10426}; + +short filt8_dcrh2[8] = { +8937,7447,5958,4468,2979,1489,0,0,}; + +short filt8_dcll2[8] = { +7447,8937,10426,11916,13405,14895,0,0}; + +short filt8_dclh2[8] = { +0,0,0,0,1489,2979,4468,5958}; diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h index e350985b0a..ef6137a07f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h +++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h @@ -133,4 +133,40 @@ extern short filt8_rr1[8]; extern short filt8_rr2[8]; +extern short filt8_rm2[8]; + +extern short filt8_rl2[8]; + +extern short filt8_l2[8]; + +extern short filt8_r2[8]; + +extern short filt8_m2[8]; + +extern short filt8_mm2[8]; + +extern short filt8_l3[8]; + +extern short filt8_r3[8]; + +extern short filt8_rr3[8]; + +extern short filt8_rl3[8]; + +extern short filt8_dcrl1[8]; + +extern short filt8_dcrh1[8]; + +extern short filt8_dcll1[8]; + +extern short filt8_dclh1[8]; + +extern short filt8_dcrl2[8]; + +extern short filt8_dcrh2[8]; + +extern short filt8_dcll2[8]; + +extern short filt8_dclh2[8]; + #endif \ No newline at end of file diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c index 161408254f..4a884b964b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_gain.c @@ -27,7 +27,7 @@ void phy_adjust_gain_nr (PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id) { - LOG_I(PHY,"Gain control: rssi %d (%d,%d)\n", + LOG_D(PHY,"Gain control: rssi %d (%d,%d)\n", rx_power_fil_dB, ue->measurements.rssi, ue->measurements.rx_power_avg_dB[eNB_id] @@ -61,7 +61,7 @@ phy_adjust_gain_nr (PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id ue->rx_total_gain_dB = MIN_RF_GAIN; } - LOG_I(PHY,"Gain control: rx_total_gain_dB = %d TARGET_RX_POWER %d (max %d,rxpf %d)\n",ue->rx_total_gain_dB,TARGET_RX_POWER,MAX_RF_GAIN,rx_power_fil_dB); + LOG_D(PHY,"Gain control: rx_total_gain_dB = %d TARGET_RX_POWER %d (max %d,rxpf %d)\n",ue->rx_total_gain_dB,TARGET_RX_POWER,MAX_RF_GAIN,rx_power_fil_dB); #ifdef DEBUG_PHY /* if ((ue->frame%100==0) || (ue->frame < 10)) diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index b49443c03c..0318ed6478 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -24,6 +24,7 @@ #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "PHY/impl_defs_top.h" +#include "executables/softmodem-common.h" #include "common/utils/LOG/vcd_signal_dumper.h" #define DEBUG_PHY @@ -33,12 +34,12 @@ // last channel estimate of the receiver void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, - PHY_VARS_NR_UE *ue, - module_id_t gNB_id, - uint8_t frame, - uint8_t subframe, - unsigned char clear, - short coef) + PHY_VARS_NR_UE *ue, + module_id_t gNB_id, + uint8_t frame, + uint8_t subframe, + unsigned char clear, + short coef) { static int max_pos_fil = 0; @@ -47,6 +48,7 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, int temp = 0, i, aa, max_val = 0, max_pos = 0; int diff; short Re,Im,ncoef; + uint8_t sync_offset = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); @@ -80,11 +82,14 @@ 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 == 0) - { diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); - if ( abs(diff) < SYNCH_HYST ) + if (frame_parms->freq_range==nr_FR2) + sync_offset = 2; + else + sync_offset = 0; + + if ( abs(diff) < (SYNCH_HYST+sync_offset) ) ue->rx_offset = 0; else ue->rx_offset = diff; @@ -100,15 +105,14 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, { first_time = 0; ue->time_sync_cell = 1; - if (ue->mac_enabled==1) { + if (get_softmodem_params()->do_ra) { LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); //mac_resynch(); - //dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id); + //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); ue->UE_mode[0] = PRACH; ue->prach_resources[gNB_id]->sync_frame = frame; ue->prach_resources[gNB_id]->init_msg1 = 0; - } - else { + } else { ue->UE_mode[0] = PUSCH; } } @@ -122,9 +126,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, #ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", + LOG_D(PHY,"AbsSubframe %d: diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", subframe, - ue->current_thread_id[subframe], diff, ue->rx_offset, clear, @@ -135,5 +138,5 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, #endif //DEBUG_PHY VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); - } + } 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 71a5771f5b..6cb0a612e9 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -24,6 +24,10 @@ #include "SCHED_NR_UE/defs.h" #include "nr_estimation.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_REFSIG/nr_refsig.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" +#include "PHY/NR_REFSIG/ptrs_nr.h" +#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" #include "filt16a_32.h" //#define DEBUG_PDSCH @@ -31,6 +35,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -48,7 +53,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, uint8_t nushift; uint8_t ssb_index=current_ssb->i_ssb; uint8_t n_hf=current_ssb->n_hf; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; nushift = ue->frame_parms.Nid_cell%4; ue->frame_parms.nushift = nushift; @@ -65,7 +70,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -192,6 +197,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -211,7 +217,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t nushift; int **dl_ch_estimates =ue->pbch_vars[eNB_offset]->dl_ch_estimates; - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; nushift = ue->frame_parms.Nid_cell%4; ue->frame_parms.nushift = nushift; @@ -233,7 +239,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -445,19 +451,19 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, assert(0); } - if( symbol == 3) + if( dmrss == 2) // update time statistics for last PBCH symbol { - // do ifft of channel estimate - for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) - for (p=0; pframe_parms.nb_antenna_ports_gNB; 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(idftsizeidx, - (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); - } - } + // do ifft of channel estimate + for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) + for (p=0; pframe_parms.nb_antenna_ports_gNB; 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, proc->thread_id, symbol, ch_offset); + idft(idftsizeidx, + (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); + } + } } //} @@ -467,6 +473,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, } int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -482,8 +489,8 @@ 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]; - 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; + int **dl_ch_estimates =ue->pdcch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage @@ -496,7 +503,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, k = coreset_start_subcarrier; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -641,10 +648,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, } int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned short p, unsigned char symbol, + unsigned short BWPStart, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch) { @@ -652,20 +661,17 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int16_t ch[2],*pil,*rxF,*dl_ch; - int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; + int16_t ch_l[2],ch_r[2],ch[2],*pil,*rxF,*dl_ch; + int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr; 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]; uint8_t nushift; - int **dl_ch_estimates =ue->pdsch_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; + int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates; + int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; - nushift = (p>>1)&1; - ue->frame_parms.nushift = nushift; - - if (ue->high_speed_flag == 0) // use second channel estimate position for temporary storage + if (ue->high_speed_flag == 0) ch_offset = ue->frame_parms.ofdm_symbol_size ; else ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -676,55 +682,103 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int re_offset = k; #ifdef DEBUG_CH - printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",ue->current_thread_id[Ns], eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,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; + // generate pilot for gNB port number 1000+p + uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart; + uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; + int8_t delta = get_delta(p, config_type); + nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000,0,nb_rb_pdsch+rb_offset); - 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; + if (config_type == pdsch_dmrs_type1){ + nushift = (p>>1)&1; + ue->frame_parms.nushift = nushift; + switch (delta) { - default: - msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); - return(-1); - break; - } + case 0://port 0,1 + fl = filt8_l0;//left interpolation Filter for DMRS config. 1 + fm = filt8_m0;//left middle interpolation Filter + fr = filt8_r0;//right interpolation Filter + fmm = filt8_mm0;;//middle middle interpolation Filter + fml = filt8_m0;//left middle interpolation Filter + fmr = filt8_mr0;//middle right interpolation Filter + fdcl = filt8_dcl0;//left DC interpolation Filter (even RB) + fdcr = filt8_dcr0;//right DC interpolation Filter (even RB) + fdclh = filt8_dcl0_h;//left DC interpolation Filter (odd RB) + fdcrh = filt8_dcr0_h;//right DC interpolation Filter (odd RB) + frl = NULL; + frr = NULL; + break; + case 1://port2,3 + 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; + frl = NULL; + frr = NULL; + break; - // generate pilot - 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); + default: + msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return -1; + break; + } + } else {//pdsch_dmrs_type2 + nushift = delta; + ue->frame_parms.nushift = nushift; + switch (delta) { + case 0://port 0,1 + fl = filt8_l2;//left interpolation Filter should be fml + fr = filt8_r2;//right interpolation Filter should be fmr + fm = filt8_l2; + fmm = filt8_r2; + fml = filt8_ml2; + fmr = filt8_mr2; + frl = filt8_rl2; + frr = filt8_rm2; + fdcl = filt8_dcl1; + fdcr = filt8_dcr1; + fdclh = filt8_dcl1_h; + fdcrh = filt8_dcr1_h; + break; + + case 2://port2,3 + fl = filt8_l3; + fm = filt8_m2; + fr = filt8_r3; + fmm = filt8_mm2; + fml = filt8_l2; + fmr = filt8_r2; + frl = filt8_rl3; + frr = filt8_rr3; + fdcl = NULL; + fdcr = NULL; + fdclh = NULL; + fdcrh = NULL; + break; + + default: + msg("pdsch_channel_estimation: nushift=%d -> ERROR\n",nushift); + return -1; + break; + } + } for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - - pil = (int16_t *)&pilot[rb_offset*((config_type==0) ? 6:4)]; + pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 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]; + re_offset = k; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)]; + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; memset(dl_ch,0,4*(ue->frame_parms.ofdm_symbol_size)); if (ue->high_speed_flag==0) // multiply previous channel estimate by ch_est_alpha @@ -737,7 +791,8 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("rxF addr %p p %d\n", rxF,p); printf("dl_ch addr %p nushift %d\n",dl_ch,nushift); #endif - //if ((ue->frame_parms.N_RB_DL&1)==0) { + + if (config_type == pdsch_dmrs_type1) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -867,7 +922,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 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)) { @@ -875,7 +929,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 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 = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)]; pil += (idxPil-2); dl_ch += (idxDC-4); dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); @@ -920,20 +974,394 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, dl_ch, 8); } + } + } else { //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| + // Treat first 4 pilots specially (left edge) + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[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 0 : rxF - > (%d,%d) addr %p ch -> (%d,%d), pil -> (%d,%d) \n",rxF[0],rxF[1],&rxF[0],ch_l[0],ch_l[1],pil[0],pil[1]); +#endif + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + + dl_ch[(0+2*nushift)] = ch[0]; + dl_ch[(1+2*nushift)] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + + multadd_real_vector_complex_scalar(fl, + ch, + dl_ch, + 8); + + pil+=2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + + multadd_real_vector_complex_scalar(fr, + ch, + dl_ch, + 8); + + dl_ch+=12; + dl_ch[0+2*nushift] = ch[0]; + dl_ch[1+2*nushift] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + dl_ch+=4; + + for (pilot_cnt=4; pilot_cnt<4*nb_rb_pdsch; pilot_cnt+=4) { + + multadd_real_vector_complex_scalar(fml, + ch, + dl_ch, + 8); + pil+=2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PDSCH + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt,rxF[0],rxF[1],ch_l[0],ch_l[1],pil[0],pil[1]); +#endif + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + +#ifdef DEBUG_PDSCH + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch_r[0],ch_r[1],pil[0],pil[1]); +#endif + + multadd_real_vector_complex_scalar(fmr, + ch, + dl_ch, + 8); + + dl_ch+=8; + dl_ch[0+2*nushift] = ch[0]; + dl_ch[1+2*nushift] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + + multadd_real_vector_complex_scalar(fm, + ch, + dl_ch, + 8); + + pil+=2; + re_offset = (re_offset+5) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_l[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + + pil+=2; + re_offset = (re_offset+1) % ue->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch_r[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch_r[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + +#ifdef DEBUG_PDSCH + printf("pilot %u : rxF - > (%d,%d) ch -> (%d,%d), pil -> (%d,%d) \n",pilot_cnt+1,rxF[0],rxF[1],ch_r[0],ch_r[1],pil[0],pil[1]); +#endif + + ch[0] = (ch_l[0]+ch_r[0])>>1; + ch[1] = (ch_l[1]+ch_r[1])>>1; + + multadd_real_vector_complex_scalar(fmm, + ch, + dl_ch, + 8); + + dl_ch+=12; + dl_ch[0+2*nushift] = ch[0]; + dl_ch[1+2*nushift] = ch[1]; + dl_ch[2+2*nushift] = ch[0]; + dl_ch[3+2*nushift] = ch[1]; + dl_ch+=4; + } + + // Treat last 2 pilots specially (right edge) + // dl_ch-2+nushift<<1 + multadd_real_vector_complex_scalar(frl, + dl_ch-2+2*nushift, + dl_ch, + 8); + + multadd_real_vector_complex_scalar(frr, + dl_ch-14+2*nushift,/*14*/ + 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) && (p<2)) { + + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; + uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + dl_ch += (idxDC-8); + dl_ch = memset(dl_ch, 0, sizeof(int16_t)*20); + + dl_ch -= 2; + + ch_r[0] = dl_ch[0]; + ch_r[1]= dl_ch[1] ; + dl_ch += 22; + ch_l[0] = dl_ch[0]; + ch_l[1]= dl_ch[1] ; + + // for proper allignment of SIMD vectors + if((ue->frame_parms.N_RB_DL&1)==0) { + dl_ch -= 20; + //Interpolate fdcrl1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrl1, + ch_r, + dl_ch, + 8); + //Interpolate fdclh1 with ch_l + multadd_real_vector_complex_scalar(filt8_dclh1, + ch_l, + dl_ch, + 8); + dl_ch += 16; + //Interpolate fdcrh1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrh1, + ch_r, + dl_ch, + 8); + //Interpolate fdcll1 with ch_l + multadd_real_vector_complex_scalar(filt8_dcll1, + ch_l, + dl_ch, + 8); + } else { + dl_ch -= 28; + //Interpolate fdcrl1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrl2, + ch_r, + dl_ch, + 8); + //Interpolate fdclh1 with ch_l + multadd_real_vector_complex_scalar(filt8_dclh2, + ch_l, + dl_ch, + 8); + dl_ch += 16; + //Interpolate fdcrh1 with ch_r + multadd_real_vector_complex_scalar(filt8_dcrh2, + ch_r, + dl_ch, + 8); + //Interpolate fdcll1 with ch_l + multadd_real_vector_complex_scalar(filt8_dcll2, + ch_l, + dl_ch, + 8); + } + } } #ifdef DEBUG_PDSCH - dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; for(uint16_t idxP=0; idxPstatus == ACTIVE) { + symbInSlot = dlsch0_harq->start_symbol + dlsch0_harq->nb_symbols; + startSymbIndex = &dlsch0_harq->start_symbol; + nbSymb = &dlsch0_harq->nb_symbols; + L_ptrs = &dlsch0_harq->PTRSTimeDensity; + K_ptrs = &dlsch0_harq->PTRSFreqDensity; + dmrsSymbPos = &dlsch0_harq->dlDmrsSymbPos; + ptrsSymbPos = &dlsch0_harq->ptrs_symbols; + ptrsSymbIdx = &dlsch0_harq->ptrs_symbol_index; + ptrsReOffset = &dlsch0_harq->PTRSReOffset; + dmrsConfigType = &dlsch0_harq->ptrs_symbol_index; + nb_rb = &dlsch0_harq->nb_rb; + } + if(dlsch1_harq) { + symbInSlot = dlsch1_harq->start_symbol + dlsch0_harq->nb_symbols; + startSymbIndex = &dlsch1_harq->start_symbol; + nbSymb = &dlsch1_harq->nb_symbols; + L_ptrs = &dlsch1_harq->PTRSTimeDensity; + K_ptrs = &dlsch1_harq->PTRSFreqDensity; + dmrsSymbPos = &dlsch1_harq->dlDmrsSymbPos; + ptrsSymbPos = &dlsch1_harq->ptrs_symbols; + ptrsSymbIdx = &dlsch1_harq->ptrs_symbol_index; + ptrsReOffset = &dlsch1_harq->PTRSReOffset; + dmrsConfigType = &dlsch1_harq->ptrs_symbol_index; + nb_rb = &dlsch1_harq->nb_rb; + } + /* loop over antennas */ + for (int aarx=0; aarxnb_antennas_rx; aarx++) { + phase_per_symbol = (int16_t*)pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx]; + ptrs_re_symbol = (int32_t*)pdsch_vars[eNB_id]->ptrs_re_per_slot[aarx]; + ptrs_re_symbol[symbol] = 0; + phase_per_symbol[(2*symbol)+1] = 0; // Imag + /* set DMRS estimates to 0 angle with magnitude 1 */ + if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { + /* set DMRS real estimation to 32767 */ + phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767 +#ifdef DEBUG_DL_PTRS + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]); +#endif + } + else { // real ptrs value is set to 0 + phase_per_symbol[2*symbol] = 0; // Real + } + + if(dlsch0_harq->status == ACTIVE) { + if(symbol == *startSymbIndex) { + *ptrsSymbPos = 0; + set_ptrs_symb_idx(ptrsSymbPos, + *nbSymb, + *startSymbIndex, + 1<< *L_ptrs, + *dmrsSymbPos); + } + /* if not PTRS symbol set current ptrs symbol index to zero*/ + *ptrsSymbIdx = 0; + /* Check if current symbol contains PTRS */ + if(is_ptrs_symbol(symbol, *ptrsSymbPos)) { + *ptrsSymbIdx = symbol; + /*------------------------------------------------------------------------------------------------------- */ + /* 1) Estimate common phase error per PTRS symbol */ + /*------------------------------------------------------------------------------------------------------- */ + nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb, + rnti, + (int16_t *)&pdsch_vars[eNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch], + nr_slot_rx, + symbol,frame_parms->ofdm_symbol_size, + (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], + ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol][0], + &phase_per_symbol[2* symbol], + &ptrs_re_symbol[symbol]); + } + }// HARQ 0 + + /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/ + if(symbol == (symbInSlot -1)) { + /*------------------------------------------------------------------------------------------------------- */ + /* 2) Interpolate PTRS estimated value in TD */ + /*------------------------------------------------------------------------------------------------------- */ + /* If L-PTRS is > 0 then we need interpolation */ + if(*L_ptrs > 0) { + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb); + if(ret != 0) { + LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); + } + } +#ifdef DEBUG_DL_PTRS + LOG_M("ptrsEst.m","est",pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); + LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp", + &pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ], + (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1); +#endif + /*------------------------------------------------------------------------------------------------------- */ + /* 3) Compensated DMRS based estimated signal with PTRS estimation */ + /*--------------------------------------------------------------------------------------------------------*/ + for(uint8_t i = *startSymbIndex; i< symbInSlot ;i++) { + /* DMRS Symbol has 0 phase so no need to rotate the respective symbol */ + /* Skip rotation if the slot processing is wrong */ + if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { +#ifdef DEBUG_DL_PTRS + printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); +#endif + rotate_cpx_vector((int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + &phase_per_symbol[2* i], + (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + ((*nb_rb) * NR_NB_SC_PER_RB), 15); + }// if not DMRS Symbol + }// symbol loop + }// last symbol check + }//Antenna loop +}//main function diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 892c6b7692..6c461ef448 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -43,6 +43,7 @@ \param symbol symbol within frame */ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -50,6 +51,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short nb_rb_coreset); int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -57,6 +59,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, NR_UE_SSB *current_ssb); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned char symbol, @@ -65,10 +68,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, uint8_t n_hf); int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, uint8_t eNB_offset, unsigned char Ns, unsigned short p, unsigned char symbol, + unsigned short BWPStart, unsigned short bwp_start_subcarrier, unsigned short nb_rb_pdsch); @@ -81,15 +86,18 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, short coef); void nr_ue_measurements(PHY_VARS_NR_UE *ue, - unsigned int subframe_offset, - unsigned char N0_symbol, - unsigned char abstraction_flag, - unsigned char rank_adaptation, - uint8_t subframe); + UE_nr_rxtx_proc_t *proc, + uint8_t slot); void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue, - uint8_t slot, - uint8_t abstraction_flag); + uint8_t gNB_index, + UE_nr_rxtx_proc_t *proc, + uint8_t slot, + uint8_t abstraction_flag); + +void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t slot); void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, @@ -97,6 +105,18 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); +void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, + NR_UE_PDSCH **pdsch_vars, + NR_DL_FRAME_PARMS *frame_parms, + NR_DL_UE_HARQ_t *dlsch0_harq, + NR_DL_UE_HARQ_t *dlsch1_harq, + uint8_t eNB_id, + uint8_t nr_slot_rx, + unsigned char symbol, + uint32_t nb_re_pdsch, + unsigned char harq_pid, + uint16_t rnti, + RX_type_t rx_type); float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 3e7352f82c..61fc40ad3f 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -19,6 +19,18 @@ * contact@openairinterface.org */ +/*! \file nr_ue_measurements.c + * \brief UE measurements routines + * \author R. Knopp, G. Casati + * \date 2020 + * \version 0.1 + * \company Eurecom, Fraunhofer IIS + * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de + * \note + * \warning + */ + +#include "executables/softmodem-common.h" #include "PHY/defs_nr_UE.h" #include "PHY/phy_extern_nr_ue.h" #include "common/utils/LOG/log.h" @@ -33,48 +45,41 @@ //#define DEBUG_MEAS_UE //#define DEBUG_RANK_EST -#if 0 -int16_t cond_num_threshold = 0; - -void print_shorts(char *s,short *x) -{ - - - printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s, - x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7] - ); - -} -void print_ints(char *s,int *x) -{ - - - printf("%s : %d,%d,%d,%d\n",s, - x[0],x[1],x[2],x[3] - ); - -} -#endif - +// Returns the pathloss in dBm for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission +// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16 +// Assumptions: +// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE +// Measurement units: +// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm) int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){ PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + int16_t pathloss; - /* - if (ue->frame_parms.mode1_flag == 1) - RSoffset = 6; - else - RSoffset = 3; - */ + if (get_softmodem_params()->do_ra){ - /* LOG_D(PHY,"get_nr_PL : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", - (1.0*dB_fixed_times10(ue->measurements.rsrp[eNB_index])-(10.0*ue->rx_total_gain_dB))/10.0, - 10*log10((double)ue->measurements.rsrp[eNB_index]), - ue->frame_parms.pdsch_config_common.referenceSignalPower);*/ + long referenceSignalPower = ue->nrUE_config.ssb_config.ss_pbch_power; + double rsrp_dBm = 10*log10(ue->measurements.rsrp[gNB_index]) + 30 - ue->rx_total_gain_dB; + + pathloss = (int16_t)(10*log10(pow(10, (double)(referenceSignalPower)/10) - pow(10, (double)(rsrp_dBm)/10))); + + LOG_D(MAC, "In %s: pathloss %d dBm, UE RX total gain %d dB, referenceSignalPower %ld dBm (%f mW), RSRP %f dBm (%f mW)\n", + __FUNCTION__, + pathloss, + ue->rx_total_gain_dB, + referenceSignalPower, + pow(10, referenceSignalPower/10), + rsrp_dBm, + pow(10, rsrp_dBm/10)); + + } else { + + pathloss = ((int16_t)(((10*ue->rx_total_gain_dB) - dB_fixed_times10(ue->measurements.rsrp[gNB_index]))/10)); + + } + + return pathloss; - return((int16_t)(((10*ue->rx_total_gain_dB) - dB_fixed_times10(ue->measurements.rsrp[gNB_index]))/10)); - // dB_fixed_times10(RSoffset*12*ue_g[Mod_id][CC_id]->frame_parms.N_RB_DL) + - //(ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10)); } uint32_t get_nr_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id) @@ -105,116 +110,84 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index) return -140.0; } - void nr_ue_measurements(PHY_VARS_NR_UE *ue, - unsigned int subframe_offset, - unsigned char N0_symbol, - unsigned char abstraction_flag, - unsigned char rank_adaptation, - uint8_t subframe) + UE_nr_rxtx_proc_t *proc, + uint8_t slot) { - int aarx,aatx,eNB_id=0; //,gain_offset=0; - //int rx_power[NUMBER_OF_CONNECTED_eNB_MAX]; - -/*#if defined(__x86_64__) || defined(__i386__) - __m128i *dl_ch0_128, *dl_ch1_128; -#elif defined(__arm__) - int16x8_t *dl_ch0_128, *dl_ch1_128get_PL; -#endif*/ - + int aarx, aatx, gNB_id = 0; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - //unsigned int limit, subband; - //int nb_subbands, subband_size, last_subband_size, *dl_ch0, *dl_ch1, N_RB_DL = frame_parms->N_RB_DL; - - int ch_offset, rank_tm3_tm4 = 0; + int ch_offset = frame_parms->ofdm_symbol_size*2; + NR_UE_DLSCH_t *dlsch = ue->dlsch[proc->thread_id][gNB_id][0]; + uint8_t harq_pid = dlsch->current_harq_pid; + int N_RB_DL = dlsch->harq_processes[harq_pid]->nb_rb; ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx; - - /*int16_t *dl_ch; - dl_ch = (int16_t *)&ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates[eNB_id][ch_offset];*/ - ch_offset = ue->frame_parms.ofdm_symbol_size*2; - -//printf("testing measurements\n"); // signal measurements + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++){ - for (eNB_id=0; eNB_idn_connected_eNB; eNB_id++) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { - for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { - ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = - (signal_energy_nodc(&ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates[eNB_id][ch_offset], - (50*12))); - //- ue->measurements.n0_power[aarx]; + ue->measurements.rx_power_tot[gNB_id] = 0; - if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0) - ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; //ue->measurements.n0_power[aarx]; + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++){ - ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); + ue->measurements.rx_power[gNB_id][aarx] = 0; - if (aatx==0) - ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; - else - ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; - } //aatx + for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){ - ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); + ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = (signal_energy_nodc(&ue->pdsch_vars[proc->thread_id][0]->dl_ch_estimates[gNB_id][ch_offset], N_RB_DL*NR_NB_SC_PER_RB)); - if (aarx==0) - ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx]; - else - ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx]; - } //aarx + if (ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]<0) + ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = 0; - ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]); + ue->measurements.rx_spatial_power_dB[gNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]); + ue->measurements.rx_power[gNB_id][aarx] += ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]; - } //eNB_id - - //printf("ue measurement addr dlch %p\n", dl_ch); + } - eNB_id=0; + ue->measurements.rx_power_dB[gNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[gNB_id][aarx]); + ue->measurements.rx_power_tot[gNB_id] += ue->measurements.rx_power[gNB_id][aarx]; - if (ue->transmission_mode[eNB_id]!=4 && ue->transmission_mode[eNB_id]!=3) - ue->measurements.rank[eNB_id] = 0; - else - ue->measurements.rank[eNB_id] = rank_tm3_tm4; - // printf ("tx mode %d\n", ue->transmission_mode[eNB_id]); - // printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]); + } + + ue->measurements.rx_power_tot_dB[gNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[gNB_id]); + + } // filter to remove jitter if (ue->init_averaging == 0) { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) - ue->measurements.rx_power_avg[eNB_id] = (int) - (((k1*((long long int)(ue->measurements.rx_power_avg[eNB_id]))) + - (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10); - //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg, - // ue->measurements.n0_power_tot); - ue->measurements.n0_power_avg = (int) - (((k1*((long long int) (ue->measurements.n0_power_avg))) + - (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) + ue->measurements.rx_power_avg[gNB_id] = (int)(((k1*((long long int)(ue->measurements.rx_power_avg[gNB_id]))) + (k2*((long long int)(ue->measurements.rx_power_tot[gNB_id])))) >> 10); + + ue->measurements.n0_power_avg = (int)(((k1*((long long int) (ue->measurements.n0_power_avg))) + (k2*((long long int) (ue->measurements.n0_power_tot))))>>10); + + LOG_D(PHY, "Noise Power Computation: k1 %lld k2 %lld n0 avg %u n0 tot %u\n", k1, k2, ue->measurements.n0_power_avg, ue->measurements.n0_power_tot); + } else { - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) - ue->measurements.rx_power_avg[eNB_id] = ue->measurements.rx_power_tot[eNB_id]; + + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) + ue->measurements.rx_power_avg[gNB_id] = ue->measurements.rx_power_tot[gNB_id]; ue->measurements.n0_power_avg = ue->measurements.n0_power_tot; ue->init_averaging = 0; + } - for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++) { - ue->measurements.rx_power_avg_dB[eNB_id] = dB_fixed( ue->measurements.rx_power_avg[eNB_id]); - ue->measurements.wideband_cqi_tot[eNB_id] = dB_fixed2(ue->measurements.rx_power_tot[eNB_id],ue->measurements.n0_power_tot); - ue->measurements.wideband_cqi_avg[eNB_id] = dB_fixed2(ue->measurements.rx_power_avg[eNB_id],ue->measurements.n0_power_avg); - ue->measurements.rx_rssi_dBm[eNB_id] = ue->measurements.rx_power_avg_dB[eNB_id] - ue->rx_total_gain_dB; -//#ifdef DEBUG_MEAS_UE - LOG_D(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", - eNB_id, - subframe, - ue->measurements.rx_rssi_dBm[eNB_id], - ue->measurements.rx_power_avg_dB[eNB_id], - ue->measurements.wideband_cqi_avg[eNB_id], - ue->measurements.rx_power_avg[eNB_id], - ue->measurements.n0_power_tot); -//#endif + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { + + ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]); + ue->measurements.wideband_cqi_tot[gNB_id] = dB_fixed2(ue->measurements.rx_power_tot[gNB_id], ue->measurements.n0_power_tot); + ue->measurements.wideband_cqi_avg[gNB_id] = dB_fixed2(ue->measurements.rx_power_avg[gNB_id], ue->measurements.n0_power_avg); + ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->rx_total_gain_dB; + + LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n", + gNB_id, + slot, + ue->measurements.rx_rssi_dBm[gNB_id], + ue->measurements.rx_power_avg_dB[gNB_id], + ue->measurements.wideband_cqi_avg[gNB_id], + ue->measurements.rx_power_avg[gNB_id], + ue->measurements.n0_power_tot); } #if defined(__x86_64__) || defined(__i386__) @@ -223,72 +196,136 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, #endif } +// This function implements: +// - SS reference signal received power (SS-RSRP) as per clause 5.1.1 of 3GPP TS 38.215 version 16.3.0 Release 16 +// - no Layer 3 filtering implemented (no filterCoefficient provided from RRC) +// Todo: +// - Layer 3 filtering according to clause 5.5.3.2 of 3GPP TS 38.331 version 16.2.0 Release 16 +// Measurement units: +// - RSRP: W (dBW) +// - RX Gain dB void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue, - uint8_t slot, - uint8_t abstraction_flag) + uint8_t gNB_id, + UE_nr_rxtx_proc_t *proc, + uint8_t slot, + uint8_t abstraction_flag) { - int aarx,rb, symbol_offset; - int16_t *rxF; + int aarx; + int nb_re; + int k_start = 55; + int k_end = 183; + unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; + uint8_t l_sss = ue->symbol_offset + 2; - uint16_t Nid_cell = ue->frame_parms.Nid_cell; - uint8_t eNB_offset=0,l,nushift; - uint16_t off,nb_rb; - NR_UE_MAC_INST_t *mac = get_mac_inst(0); - int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[slot]].rxdataF; + if (ssb_offset>= ue->frame_parms.ofdm_symbol_size){ - nushift = ue->frame_parms.Nid_cell%4; - ue->frame_parms.nushift = nushift; - unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; - if (ssb_offset>= ue->frame_parms.ofdm_symbol_size) ssb_offset-=ue->frame_parms.ofdm_symbol_size; - - symbol_offset = ue->frame_parms.ofdm_symbol_size*(ue->symbol_offset+1); + ssb_offset -= ue->frame_parms.ofdm_symbol_size; - ue->measurements.rsrp[eNB_offset] = 0; + } - //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ - nb_rb = 20; - //} else{ - // LOG_E(PHY,"report quantity not supported \n"); - //} + ue->measurements.rsrp[gNB_id] = 0; - if (abstraction_flag == 0) { + if (abstraction_flag == 0) { - for (l=0; l<1; l++) { + LOG_D(PHY, "In %s: [UE %d] slot %d l_sss %d ssb_offset %d\n", __FUNCTION__, ue->Mod_id, slot, l_sss, ssb_offset); - LOG_D(PHY,"[UE %d] slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, l %d)\n",ue->Mod_id,slot,Nid_cell,nushift, - eNB_offset,l); + nb_re = 0; - for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+ssb_offset+nushift)]; - off = 0; + for (aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { - if (l==0) { - for (rb=0; rbcommon_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; - ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])); - //printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]))); + for(int k = k_start; k < k_end; k++){ + + #ifdef DEBUG_MEAS_UE + LOG_I(PHY, "In %s rxF_sss %d %d\n", __FUNCTION__, rxF_sss[k*2], rxF_sss[k*2 + 1]); + #endif + + ue->measurements.rsrp[gNB_id] += (((int32_t)rxF_sss[k*2]*rxF_sss[k*2]) + ((int32_t)rxF_sss[k*2 + 1]*rxF_sss[k*2 + 1])); + + nb_re++; - off = (off+4) % ue->frame_parms.ofdm_symbol_size; - } - } - } } - - ue->measurements.rsrp[eNB_offset]/=nb_rb; - - } else { - - ue->measurements.rsrp[eNB_offset] = -93 ; } + ue->measurements.rsrp[gNB_id] /= nb_re; - if (eNB_offset == 0) + } else { - LOG_I(PHY,"[UE %d] slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d)\n", - ue->Mod_id, - slot,eNB_offset, - (eNB_offset>0) ? ue->measurements.adj_cell_id[eNB_offset-1] : ue->frame_parms.Nid_cell, - 10*log10(ue->measurements.rsrp[eNB_offset])-ue->rx_total_gain_dB, - ue->measurements.rsrp[eNB_offset]); + ue->measurements.rsrp[gNB_id] = -93; + + } + + ue->measurements.rsrp_filtered[gNB_id] = ue->measurements.rsrp[gNB_id]; + + LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %3.1f dBm/RE (%d W)\n", + __FUNCTION__, + ue->Mod_id, + slot, + 10*log10(ue->measurements.rsrp[gNB_id]) + 30 - ue->rx_total_gain_dB, + ue->measurements.rsrp[gNB_id]); + +} + +void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t slot){ + + uint8_t k; + int aarx, nb_nulls; + int16_t *rxF_sss; + uint8_t k_left = 48; + uint8_t k_right = 183; + uint8_t k_length = 8; + uint8_t l_sss = ue->symbol_offset + 2; + unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; + ue->measurements.n0_power_tot = 0; + + LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss); + + for (aarx = 0; aarxframe_parms.nb_antennas_rx; aarx++) { + + nb_nulls = 0; + ue->measurements.n0_power[aarx] = 0; + rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; + + //-ve spectrum from SSS + for(k = k_left; k < k_left + k_length; k++){ + + #ifdef DEBUG_MEAS_RRC + LOG_I(PHY, "In %s -rxF_sss %d %d\n", __FUNCTION__, rxF_sss[k*2], rxF_sss[k*2 + 1]); + #endif + + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[k*2]*rxF_sss[k*2]) + ((int32_t)rxF_sss[k*2 + 1]*rxF_sss[k*2 + 1])); + nb_nulls++; + + } + + //+ve spectrum from SSS + for(k = k_right; k < k_right + k_length; k++){ + + #ifdef DEBUG_MEAS_RRC + LOG_I(PHY, "In %s +rxF_sss %d %d\n", __FUNCTION__, rxF_sss[k*2], rxF_sss[k*2 + 1]); + #endif + + ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[k*2]*rxF_sss[k*2]) + ((int32_t)rxF_sss[k*2 + 1]*rxF_sss[k*2 + 1])); + nb_nulls++; + + } + + ue->measurements.n0_power[aarx] /= nb_nulls; + ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]); + ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; + + } + + ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/aarx); + + #ifdef DEBUG_MEAS_RRC + int nf_usrp = ue->measurements.n0_power_tot_dB + 30 - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - 90 - (-174 + dB_fixed(30000/*scs*/) + dB_fixed(ue->frame_parms.ofdm_symbol_size)); + LOG_D(PHY, "In %s slot %d NF USRP %d dBm\n", __FUNCTION__, nf_usrp); + #endif + + LOG_D(PHY, "In %s slot %d Noise Level %d ue->measurements.n0_power_tot_dB %d \n", __FUNCTION__, slot, ue->measurements.n0_power_tot, ue->measurements.n0_power_tot_dB); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 53456bb691..bfec64820b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -36,6 +36,8 @@ #include #endif +#include +#include #include "executables/softmodem-common.h" #include "nr_transport_proto_ue.h" @@ -79,12 +81,14 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, uint32_t *z, - NR_DL_FRAME_PARMS *frame_parms, uint8_t coreset_time_dur, uint32_t coreset_nbr_rb, uint8_t reg_bundle_size_L, uint8_t coreset_interleaver_size_R, - uint8_t n_shift) { + uint8_t n_shift, + uint8_t number_of_candidates, + uint16_t *CCE, + uint8_t *L) { /* * This function will do demapping and deinterleaving from llr containing demodulated symbols * Demapping will regroup in REG and bundles @@ -120,43 +124,71 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, | REG 0 (bundle 0) bundle 0 bundle 0 */ - int c=0,r=0; - uint16_t bundle_j=0, f_bundle_j=0,f_reg=0; - uint32_t coreset_C=0; + int c = 0, r = 0; + uint16_t bundle_j = 0, f_bundle_j = 0, f_reg = 0; + uint32_t coreset_C = 0; uint16_t index_z, index_llr; int coreset_interleaved = 0; - if (reg_bundle_size_L!=0) { // interleaving will be done only if reg_bundle_size_L != 0 - coreset_interleaved=1; - coreset_C = (uint32_t)((coreset_nbr_rb * coreset_time_dur)/ (coreset_interleaver_size_R*reg_bundle_size_L)); + if (reg_bundle_size_L != 0) { // interleaving will be done only if reg_bundle_size_L != 0 + coreset_interleaved = 1; + coreset_C = (uint32_t) ((coreset_nbr_rb * coreset_time_dur) / (coreset_interleaver_size_R * reg_bundle_size_L)); } else { - reg_bundle_size_L=6; + reg_bundle_size_L = 6; } - for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) { - if ((reg%reg_bundle_size_L) == 0) { + + int f_bundle_j_list[NR_MAX_PDCCH_AGG_LEVEL] = {}; + + for (int reg = 0; reg < ((coreset_nbr_rb * coreset_time_dur)); reg++) { + if ((reg % reg_bundle_size_L) == 0) { if (r == coreset_interleaver_size_R) { - r=0; + r = 0; c++; } - bundle_j = (c*coreset_interleaver_size_R)+r; - f_bundle_j = ((r*coreset_C)+c+n_shift)%((coreset_nbr_rb*coreset_time_dur)/reg_bundle_size_L); + bundle_j = (c * coreset_interleaver_size_R) + r; + f_bundle_j = ((r * coreset_C) + c + n_shift) % ((coreset_nbr_rb * coreset_time_dur) / reg_bundle_size_L); - if (coreset_interleaved==0) f_bundle_j=bundle_j; + if (coreset_interleaved == 0) f_bundle_j = bundle_j; + + f_bundle_j_list[reg / 6] = f_bundle_j; - LOG_DNL("[r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); } + if ((reg % reg_bundle_size_L) == 0) r++; + } - f_reg = (f_bundle_j*reg_bundle_size_L)+(reg%reg_bundle_size_L); + + // Get cce_list indices by reg_idx in ascending order + int f_bundle_j_list_id = 0; + int f_bundle_j_list_ord[NR_MAX_PDCCH_AGG_LEVEL] = {}; + for (int c_id = 0; c_id < number_of_candidates; c_id++ ) { + f_bundle_j_list_id = CCE[c_id]; + for (int p = 0; p < NR_MAX_PDCCH_AGG_LEVEL; p++) { + for (int p2 = CCE[c_id]; p2 < CCE[c_id] + L[c_id]; p2++) { + if (f_bundle_j_list[p2] == p) { + f_bundle_j_list_ord[f_bundle_j_list_id] = p; + f_bundle_j_list_id++; + break; + } + } + } + } + + + for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) { + + f_reg = (f_bundle_j_list_ord[reg/6]*reg_bundle_size_L)+(reg%reg_bundle_size_L); 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 LOG_D(PHY,"[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++; @@ -369,27 +401,30 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, 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; + c_rb = 0; for (int rb=0;rb>3] & (1<<(c_rb_by6&7))) == 0) c_rb+=6; + while ((coreset_freq_dom[c_rb_by6>>3] & (1<<(7-(c_rb_by6&7)))) == 0) { + c_rb+=6; + c_rb_by6 = c_rb/6; + } 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 (((c_rb + n_BWP_start) < (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)))]; + rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; 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)))); } - if ((c_rb >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { + if (((c_rb + n_BWP_start) >= (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 + rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; // we point at the 1st part of the rxdataF in symbol 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)))); //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 @@ -399,29 +434,29 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //#endif } - if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { + if (((c_rb + n_BWP_start) < (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): odd case - rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; + rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; #ifdef NR_PDCCH_DCI_DEBUG 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 } - if ((c_rb > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { + if (((c_rb + n_BWP_start) > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // number of RBs is odd and c_rb is higher than half system bandwidth + 1 // 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 + rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; // we point at the 1st part of the rxdataF in symbol #ifdef NR_PDCCH_DCI_DEBUG 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 } - if ((c_rb == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC + if (((c_rb + n_BWP_start) == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC // if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC) // 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)))]; + rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; #ifdef NR_PDCCH_DCI_DEBUG 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)))); @@ -665,12 +700,13 @@ 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) { + UE_nr_rxtx_proc_t *proc) { + uint32_t frame = proc->frame_rx; + uint32_t slot = proc->nr_slot_rx; 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]; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0]; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; uint8_t log2_maxh, aarx; @@ -684,7 +720,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) { LOG_D(PHY,"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[slot]].rxdataF, + nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, pdcch_vars->dl_ch_estimates, pdcch_vars->rxdataF_ext, pdcch_vars->dl_ch_estimates_ext, @@ -752,12 +788,14 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, LOG_D(PHY,"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); + rel15->coreset.ShiftIndex, + rel15->number_of_candidates, + rel15->CCE, + rel15->L); /* nr_pdcch_unscrambling(rel15->rnti, frame_parms, @@ -776,8 +814,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif -void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, - uint8_t nr_tti_rx, +#if 0 +void nr_pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, + uint8_t nr_slot_rx, uint8_t *e, uint32_t length) { int i; @@ -785,7 +824,7 @@ void pdcch_scrambling(NR_DL_FRAME_PARMS *frame_parms, uint32_t x1, x2, s=0; reset = 1; // x1 is set in lte_gold_generic - x2 = (nr_tti_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 + x2 = (nr_slot_rx<<9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 for (i=0; i>(i&0x1f))&1); } } +#endif #ifdef NR_PDCCH_DCI_RUN @@ -836,11 +876,10 @@ void nr_pdcch_unscrambling(int16_t *z, #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) { + UE_nr_rxtx_proc_t *proc, + fapi_nr_dci_indication_t *dci_ind) { - NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[slot]][0]; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0]; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; for (int i=0;inb_search_space;i++) { @@ -880,9 +919,10 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, n_rnti = rel15->rnti; if (crc == n_rnti) { - LOG_D(PHY,"Decoded crc %x matches rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]); - dci_ind->SFN = frame; - dci_ind->slot = slot; + LOG_D(PHY, "(%i.%i) Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n", + proc->frame_rx, proc->nr_slot_rx,n_rnti,rel15->dci_format_options[k],CCEind,dci_length,*(unsigned long long*)dci_estimation); + dci_ind->SFN = proc->frame_rx; + dci_ind->slot = proc->nr_slot_rx; dci_ind->dci_list[dci_ind->number_of_dcis].rnti = n_rnti; dci_ind->dci_list[dci_ind->number_of_dcis].n_CCE = CCEind; dci_ind->dci_list[dci_ind->number_of_dcis].dci_format = rel15->dci_format_options[k]; @@ -891,7 +931,7 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, dci_ind->number_of_dcis++; break; // If DCI is found, no need to check for remaining DCI lengths } else { - LOG_D(PHY,"Decoded crc %x does not match rnti %x for DCI format %d\n", crc, n_rnti, rel15->dci_format_options[k]); + LOG_D(PHY,"(%i.%i) Decoded crc %x does not match rnti %x for DCI format %d\n", proc->frame_rx, proc->nr_slot_rx, crc, n_rnti, rel15->dci_format_options[k]); } } } @@ -906,7 +946,7 @@ void nr_dci_decoding_procedure0(int s, uint16_t coreset_nbr_rb, NR_UE_PDCCH **pdcch_vars, int do_common, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, NR_DCI_ALLOC_t *dci_alloc, int16_t eNB_id, uint8_t current_thread_id, @@ -941,7 +981,7 @@ void nr_dci_decoding_procedure0(int s, LOG_DDD("format_found is %d \n", *format_found); //if (mode == NO_DCI) { // #ifdef NR_PDCCH_DCI_DEBUG - // LOG_DDD("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_slot_rx %d in current searchSpace\n", nr_slot_rx); // #endif // return; //} @@ -975,8 +1015,8 @@ void nr_dci_decoding_procedure0(int s, // } // if (mode == NO_DCI) { -// LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_tti_rx %d\n", -// nr_tti_rx); +// LOG_D(PHY, "skip DCI decoding: expect no DCIs at nr_slot_rx %d\n", +// nr_slot_rx); // return; // } @@ -1047,7 +1087,7 @@ void nr_dci_decoding_procedure0(int s, // compute Yk Yk = (unsigned int) pdcch_vars[eNB_id]->crnti; - for (i = 0; i <= nr_tti_rx; i++) + for (i = 0; i <= nr_slot_rx; i++) Yk = (Yk * A[p%3]) % 65537; } @@ -1316,7 +1356,7 @@ 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; + pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // if (crc == si_rnti) { // dci_alloc[*dci_cnt].format = format_si; @@ -1327,7 +1367,7 @@ void nr_dci_decoding_procedure0(int s, // } 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; + // pdcch_vars[eNB_id]->nCCE[nr_slot_rx] = CCEind; // *dci_cnt = *dci_cnt + 1; // } else if (crc == pdcch_vars[eNB_id]->crnti) { @@ -1338,23 +1378,23 @@ void nr_dci_decoding_procedure0(int s, // dci_alloc[*dci_cnt].format = format0; // *format0_found = 1; // *dci_cnt = *dci_cnt + 1; - // pdcch_vars[eNB_id]->nCCE[nr_tti_rx] = CCEind; + // pdcch_vars[eNB_id]->nCCE[nr_slot_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; + // pdcch_vars[eNB_id]->nCCE[nr_slot_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; + // pdcch_vars[eNB_id]->nCCE[nr_slot_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); + //LOG_I(PHY,"DCI decoding CRNTI [format: %d, nCCE[nr_slot_rx: %d]: %d ], AggregationLevel %d \n",format_c, nr_slot_rx, pdcch_vars[eNB_id]->nCCE[nr_slot_rx],L2); // memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes); switch (1 << L) { case 1: @@ -1421,7 +1461,7 @@ uint8_t nr_dci_decoding_procedure(int s, NR_DCI_ALLOC_t *dci_alloc, NR_SEARCHSPACE_TYPE_t searchSpacetype, int16_t eNB_id, - uint8_t nr_tti_rx, + uint8_t nr_slot_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, @@ -1429,16 +1469,16 @@ uint8_t nr_dci_decoding_procedure(int s, format_found_t *format_found, uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) { // uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - LOG_DD("(nr_dci_decoding_procedure) nr_tti_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n", - nr_tti_rx,n_RB_ULBWP,n_RB_DLBWP,*format_found); + LOG_DD("(nr_dci_decoding_procedure) nr_slot_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n", + nr_slot_rx,n_RB_ULBWP,n_RB_DLBWP,*format_found); int do_common = (int)searchSpacetype; uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS]; crc_scrambled_t crc_scrambled_ = *crc_scrambled; format_found_t format_found_ = *format_found; uint8_t dci_cnt = 0, old_dci_cnt = 0; uint32_t CCEmap0 = 0, CCEmap1 = 0, CCEmap2 = 0; - NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]]; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; + NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_slot_rx]]; + NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_slot_rx]][eNB_id]; uint16_t pdcch_DMRS_scrambling_id = pdcch_vars2->coreset[p].pdcchDMRSScramblingID; uint64_t coreset_freq_dom = pdcch_vars2->coreset[p].frequencyDomainResources; int coreset_time_dur = pdcch_vars2->coreset[p].duration; @@ -1452,7 +1492,7 @@ uint8_t nr_dci_decoding_procedure(int s, coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_time_dur,coreset_nbr_rb, NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - //uint8_t mi;// = get_mi(&ue->frame_parms, nr_tti_rx); + //uint8_t mi;// = get_mi(&ue->frame_parms, nr_slot_rx); //uint8_t tmode = ue->transmission_mode[eNB_id]; //uint8_t frame_type = frame_parms->frame_type; uint8_t format_0_0_1_0_size_bits = 0, format_0_0_1_0_size_bytes = 0; //FIXME @@ -1487,7 +1527,7 @@ uint8_t nr_dci_decoding_procedure(int s, * Possible overlap between RE for SS/PBCH blocks (described in section 10, 38.213) has not been implemented yet * This can be implemented by setting variable 'mode = NO_DCI' when overlap occurs */ - //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_tti_rx); + //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_slot_rx); LOG_DD("searSpaceType=%d\n",do_common); LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format); @@ -1517,7 +1557,7 @@ uint8_t nr_dci_decoding_procedure(int s, // blind decoding (Type0-PDCCH,Type0A-PDCCH,Type1-PDCCH,Type2-PDCCH) // for format0_0 => we are NOT implementing format0_0 for common search spaces. FIXME! // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1528,7 +1568,7 @@ uint8_t nr_dci_decoding_procedure(int s, 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, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat0_0_and_1_0, uformat0_0_and_1_0, format_0_0_1_0_size_bits, format_0_0_1_0_size_bytes, &dci_cnt, @@ -1537,7 +1577,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (dci_cnt != old_dci_cnt) { // we will exit the loop as we have found the DCI aggregationLevel = 5; - format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,crc_scrambled_,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes, + format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_slot_rx,p,crc_scrambled_,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes, 0); // after decoding dci successfully we recalculate dci pdu size with correct crc scrambled to get the right field sizes old_dci_cnt = dci_cnt; @@ -1552,7 +1592,7 @@ uint8_t nr_dci_decoding_procedure(int s, // or TPC-PUSCH-RNTI, or TPC-PUCCH-RNTI, or TPC-SRS-RNTI, or C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI if (css_dci_format == cformat2_0) { // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1562,7 +1602,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevelSFI, cformat2_0, uformat0_0_and_1_0, format_2_0_size_bits, format_2_0_size_bytes, &dci_cnt, @@ -1582,7 +1622,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (css_dci_format == cformat2_1) { // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1592,7 +1632,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat2_1, uformat0_0_and_1_0, format_2_1_size_bits, format_2_1_size_bytes, &dci_cnt, @@ -1612,7 +1652,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (css_dci_format == cformat2_2) { // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1622,7 +1662,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat2_2, uformat0_0_and_1_0, format_2_2_size_bits, format_2_2_size_bytes, &dci_cnt, @@ -1642,7 +1682,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (css_dci_format == cformat2_3) { // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1652,7 +1692,7 @@ uint8_t nr_dci_decoding_procedure(int s, css_dci_format,(1<current_thread_id[nr_tti_rx], frame_parms, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat2_3, uformat0_0_and_1_0, format_2_3_size_bits, format_2_3_size_bytes, &dci_cnt, @@ -1673,7 +1713,7 @@ uint8_t nr_dci_decoding_procedure(int s, // UE-specific search space for a DCI format with CRC scrambled by C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI if (uss_dci_format == uformat0_0_and_1_0) { // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1684,7 +1724,7 @@ uint8_t nr_dci_decoding_procedure(int s, 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, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat0_0_and_1_0, uformat0_0_and_1_0, format_0_0_1_0_size_bits, format_0_0_1_0_size_bytes, &dci_cnt, @@ -1704,7 +1744,7 @@ uint8_t nr_dci_decoding_procedure(int s, if (uss_dci_format == uformat0_1_and_1_1) { // 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_bits = nr_dci_format_size(ue,eNB_id,nr_slot_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); 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); @@ -1715,7 +1755,7 @@ uint8_t nr_dci_decoding_procedure(int s, 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, + nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_slot_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_slot_rx], frame_parms, crc_scrambled_values, aggregationLevel, cformat0_0_and_1_0, uformat0_1_and_1_1, format_0_1_1_1_size_bits, format_0_1_1_1_size_bytes, &dci_cnt, diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c index 347c9c2ab9..fa09093306 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c @@ -59,7 +59,7 @@ -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 slot) { /* #ifdef DEBUG_DCI if (frame_parms->frame_type == TDD) @@ -69,11 +69,11 @@ uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8 #endif */ uint8_t ret = 255; - uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe))); + uint8_t subframe = slot / frame_parms->slots_per_subframe; AssertFatal(1==0,"Not ready for this ...\n"); if (frame_parms->frame_type == FDD) { - ret = (((frame<<1)+nr_tti_rx)&7); + ret = (((frame<<1)+slot)&7); } else { } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 7378f69c27..429bd9a836 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -44,7 +44,7 @@ #include "executables/nr-uesoftmodem.h" #include "PHY/CODING/nrLDPC_extern.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" -//#define DEBUG_DLSCH_DECODING + //#define ENABLE_PHY_PAYLOAD_DEBUG 1 //#define OAI_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX @@ -56,7 +56,23 @@ notifiedFIFO_t freeBlocks_dl; notifiedFIFO_elt_t *msgToPush_dl; int nbDlProcessing =0; + +static tpool_t pool_dl; + //extern double cpuf; +void init_dlsch_tpool(uint8_t num_dlsch_threads) +{ + if( num_dlsch_threads==0) + return; + + char *params=calloc(1,(num_dlsch_threads*3)+1); + for (int i=0; imax_ldpc_iterations = max_ldpc_iterations; for (i=0; iharq_processes[i] = (NR_DL_UE_HARQ_t *)malloc16(sizeof(NR_DL_UE_HARQ_t)); if (dlsch->harq_processes[i]) { @@ -188,7 +203,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint return(dlsch); } - printf("new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag); + LOG_D(PHY,"new_ue_dlsch with size %zu: exit_flag = %u\n",sizeof(NR_DL_UE_HARQ_t), exit_flag); free_nr_ue_dlsch(&dlsch,N_RB_DL); return(NULL); @@ -218,16 +233,18 @@ void nr_dlsch_unscrambling(int16_t* llr, } uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - short *dlsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t *dlsch, - NR_DL_UE_HARQ_t *harq_process, - uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint8_t is_crnti, - uint8_t llr8_flag) + UE_nr_rxtx_proc_t *proc, + int eNB_id, + short *dlsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + NR_UE_DLSCH_t *dlsch, + NR_DL_UE_HARQ_t *harq_process, + uint32_t frame, + uint16_t nb_symb_sch, + uint8_t nr_slot_rx, + uint8_t harq_pid, + uint8_t is_crnti, + uint8_t llr8_flag) { #if UE_TIMING_TRACE @@ -239,7 +256,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint32_t G; uint32_t ret,offset; int32_t no_iteration_ldpc, length_dec; - uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bytes_F,err_flag=0; + uint32_t r,r_offset=0,Kr=8424,Kr_bytes,K_bits_F,err_flag=0; uint8_t crc_type; int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); t_nrLDPC_dec_params decParams; @@ -248,18 +265,20 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_time_stats* p_procTime =&procTime ; if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); + LOG_E(PHY,"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; + // HARQ stats + phy_vars_ue->dl_stats[harq_process->round]++; int16_t z [68*384]; int8_t l [68*384]; //__m128i l; //int16_t inv_d [68*384]; uint8_t kc; - uint8_t Ilbrm = 0; + uint8_t Ilbrm = 1; uint32_t Tbslbrm;// = 950984; uint16_t nb_rb;// = 30; @@ -275,7 +294,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups; } 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; @@ -287,23 +305,23 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, //NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[0]; if (!dlsch_llr) { - printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); + LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n"); return(dlsch->max_ldpc_iterations + 1); } if (!frame_parms) { - printf("dlsch_decoding.c: NULL frame_parms pointer\n"); + LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n"); return(dlsch->max_ldpc_iterations + 1); } - /*if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) { - printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx); + /*if (nr_slot_rx> (frame_parms->slots_per_frame-1)) { + printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx); return(dlsch->max_ldpc_iterations + 1); }*/ /*if (harq_process->harq_ack.ack != 2) { LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", - phy_vars_ue->Mod_id, nr_tti_rx, harq_process->harq_ack.ack); + phy_vars_ue->Mod_id, nr_slot_rx, harq_process->harq_ack.ack); }*/ // nb_rb = dlsch->nb_rb; @@ -314,7 +332,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(max_ldpc_iterations + 1); }*/ - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; + /*harq_pid = dlsch->current_harq_pid[proc->thread_id]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_ldpc_iterations + 1); @@ -343,42 +361,38 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, else Coderate = (float) (harq_process->R) /(float) 2048; - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) + if ((A <=292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; + kc = 52; if (Coderate < 0.3333){ p_decParams->R = 15; - kc = 52; } else if (Coderate <0.6667){ p_decParams->R = 13; - kc = 32; } else { p_decParams->R = 23; - kc = 17; } } else{ p_decParams->BG = 1; + kc = 68; if (Coderate < 0.6667){ p_decParams->R = 13; - kc = 68; } else if (Coderate <0.8889){ p_decParams->R = 23; - kc = 35; } else { p_decParams->R = 89; - kc = 27; } } if (harq_process->round == 0) { - // This is a new packet, so compute quantities regarding segmentation - if (A > 3824) + // This is a new packet, so compute quantities regarding segmentation + if (A > NR_MAX_PDSCH_TBS) harq_process->B = A+24; else harq_process->B = A+16; @@ -392,12 +406,10 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, &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 + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD) && (!frame%100)) + LOG_I(PHY,"K %d C %d Z %d nl %d \n", harq_process->K, harq_process->C, p_decParams->Z, harq_process->Nl); } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); p_decParams->Z = harq_process->Z; @@ -423,16 +435,15 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return((1+dlsch->max_ldpc_iterations)); } -#ifdef DEBUG_DLSCH_DECODING - printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + LOG_I(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); + opp_enabled=1; Kr = harq_process->K; // [hna] overwrites this line "Kr = p_decParams->Z*kb" Kr_bytes = Kr>>3; - - K_bytes_F = Kr_bytes-(harq_process->F>>3); + K_bits_F = Kr-harq_process->F; for (r=0; rC; r++) { @@ -453,8 +464,6 @@ 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_OUT); - //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); #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -508,31 +517,21 @@ 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); - r_offset += E; -#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],E,1,0); - } + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + { + LOG_I(PHY,"decoder input(segment %u) :",r); + for (int i=0;id[r][i]); + LOG_D(PHY,"\n"); + } - printf("decoder input(segment %u) :",r); - int i; - for (i=0;id[r][i]); - printf("\n"); -#endif - - // printf("Clearing c, %p\n",harq_process->c[r]); memset(harq_process->c[r],0,Kr_bytes); - // printf("done\n"); + if (harq_process->C == 1){ - if (A > 3824) + if (A > NR_MAX_PDSCH_TBS) crc_type = CRC24_A; else crc_type = CRC16; @@ -551,28 +550,17 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, start_meas(dlsch_turbo_decoding_stats); #endif - //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); - //printf("harq process dr iteration %d\n", p_decParams->numMaxIter); - - memset(pv,0,2*harq_process->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)); - - - 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])); - } - // 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])); - } - - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + //set first 2*Z_c bits to zeros + memset(&z[0],0,2*harq_process->Z*sizeof(int16_t)); + //set Filler bits + memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t)); + //Move coded bits before filler bits + memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t)); + //skip filler bits + memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t)); + //Saturate coded bits before decoding into 8 bits values + for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } @@ -590,15 +578,16 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // 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)) { LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r); - if (r==0) - for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]); + if (r==0) { + for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]); + } //Temporary hack no_iteration_ldpc = dlsch->max_ldpc_iterations; ret = no_iteration_ldpc; } else { - LOG_D(PHY,"CRC NOK\n\033[0m"); + LOG_D(PHY,"CRC NOT OK\n\033[0m"); ret = 1 + dlsch->max_ldpc_iterations; } @@ -608,24 +597,17 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, nb_error_decod++; } - //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); - //} - //else - //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); - for (int m=0; m < Kr>>3; m ++) { harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; } -#ifdef DEBUG_DLSCH_DECODING - //printf("output decoder %d %d %d %d %d \n", harq_process->c[r][0], harq_process->c[r][1], harq_process->c[r][2],harq_process->c[r][3], harq_process->c[r][4]); - for (int k=0;k>3;k++) - printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - printf("no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); - //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + { + for (int k=0;k>3;k++) + LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + LOG_D(PHY,"no_iterations_ldpc %d (ret %u)\n",no_iteration_ldpc,ret); + } #if UE_TIMING_TRACE @@ -633,58 +615,39 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, #endif } - - - /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f dlsch_turbo_decoding_stats %5.3f \n", - harq_process->C, - r, - dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0), - dlsch_deinterleaving_stats->p_time/(cpuf*1000.0), - dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/ - if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// 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); + LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); err_flag = 1; } } - int32_t frame_rx_prev = frame; - int32_t tti_rx_prev = nr_tti_rx - 1; - if (tti_rx_prev < 0) { - frame_rx_prev--; - tti_rx_prev += 10*frame_parms->ttis_per_subframe; - } - frame_rx_prev = frame_rx_prev%1024; - if (err_flag == 1) { -//#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 + phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); + 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]++; - // printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round); if (harq_process->round >= dlsch->Mlimit) { harq_process->status = SCH_IDLE; harq_process->round = 0; + phy_vars_ue->dl_stats[4]++; } if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mdlharq,harq_process->TBS); } return((1 + dlsch->max_ldpc_iterations)); } else { -//#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 + + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); harq_process->status = SCH_IDLE; harq_process->round = 0; @@ -697,7 +660,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS); } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); @@ -708,11 +671,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, Kr = harq_process->K; Kr_bytes = Kr>>3; - /* - printf("harq_pid %d\n",harq_pid); - printf("F %d, Fbytes %d\n",harq_process->F,harq_process->F>>3); - printf("C %d\n",harq_process->C); - */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_IN); @@ -723,30 +681,22 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, 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 %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], + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + { + LOG_D(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes); + LOG_D(PHY,"copied %d bytes to b sequence (harq_pid %d)\n", + (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); + LOG_D(PHY,"b[0] = %p,c[%d] = %p\n", + (void *)(uint64_t)(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]); - } + (void *)(uint64_t)(harq_process->c[r]) ); + if (frame%100 == 0){ + LOG_D (PHY, "Printing 10 first payload bytes at frame: %d ", frame); + for (int i = 0; i <10 ; i++){ //Kr_bytes + LOG_D(PHY, "[%d] : %x ", i, harq_process->b[i]); } -#endif - + } + } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_COMBINE_SEG, VCD_FUNCTION_OUT); @@ -756,7 +706,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, return(ret); } -#ifdef UE_DLSCH_PARALLELISATION + uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, int eNB_id, @@ -766,7 +716,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, uint16_t nb_symb_sch, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag) @@ -780,7 +730,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, uint32_t A,E; uint32_t G; uint32_t ret,offset; - uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bytes_F; + uint32_t r,r_offset=0,Kr=8424,Kr_bytes,err_flag=0,K_bits_F; uint8_t crc_type; //UE_rxtx_proc_t *proc = &phy_vars_ue->proc; int32_t no_iteration_ldpc,length_dec; @@ -794,35 +744,29 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, t_nrLDPC_time_stats* p_procTime =&procTime ; int8_t llrProcBuf[NR_LDPC_MAX_NUM_LLR] __attribute__ ((aligned(32))); if (!harq_process) { - printf("dlsch_decoding.c: NULL harq_process pointer\n"); + LOG_E(PHY,"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 kc; uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; double Coderate = 0.0; uint8_t dmrs_type = harq_process->dmrsConfigType; - //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; - if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) + if (dmrs_type == NFAPI_NR_DMRS_TYPE1) nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups; else nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups; - uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); - + uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos); + uint32_t i,j; -// int nbDlProcessing =0; __m128i *pv = (__m128i*)&z; __m128i *pl = (__m128i*)&l; @@ -832,25 +776,25 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_IN); if (!dlsch_llr) { - printf("dlsch_decoding.c: NULL dlsch_llr pointer\n"); + LOG_E(PHY,"dlsch_decoding.c: NULL dlsch_llr pointer\n"); return(dlsch->max_ldpc_iterations); } if (!frame_parms) { - printf("dlsch_decoding.c: NULL frame_parms pointer\n"); + LOG_E(PHY,"dlsch_decoding.c: NULL frame_parms pointer\n"); return(dlsch->max_ldpc_iterations); } - /* if (nr_tti_rx> (10*frame_parms->ttis_per_subframe-1)) { - printf("dlsch_decoding.c: Illegal subframe index %d\n",nr_tti_rx); + /* if (nr_slot_rx> (frame_parms->slots_per_frame-1)) { + printf("dlsch_decoding.c: Illegal slot index %d\n",nr_slot_rx); return(dlsch->max_ldpc_iterations); } - if (dlsch->harq_ack[nr_tti_rx].ack != 2) { + if (dlsch->harq_ack[nr_slot_rx].ack != 2) { LOG_D(PHY, "[UE %d] DLSCH @ SF%d : ACK bit is %d instead of DTX even before PDSCH is decoded!\n", - phy_vars_ue->Mod_id, nr_tti_rx, dlsch->harq_ack[nr_tti_rx].ack); + phy_vars_ue->Mod_id, nr_slot_rx, dlsch->harq_ack[nr_slot_rx].ack); }*/ /* @@ -859,7 +803,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(max_ldpc_iterations); }*/ - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; + /*harq_pid = dlsch->current_harq_pid[proc->thread_id]; if (harq_pid >= 8) { printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); return(max_ldpc_iterations); @@ -869,6 +813,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 stats + phy_vars_ue->dl_stats[harq_process->round]++; + 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, 0, harq_process->Nl); @@ -887,50 +834,44 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, proc->decoder_main_available = 1; proc->decoder_thread_available = 0; proc->decoder_thread_available1 = 0; - //get_G(frame_parms,nb_rb,dlsch->rb_alloc,mod_order,num_pdcch_symbols,phy_vars_ue->frame,subframe); - // printf("DLSCH Decoding, harq_pid %d Ndi %d\n",harq_pid,harq_process->Ndi); if ((harq_process->R)<1024) Coderate = (float) (harq_process->R) /(float) 1024; else Coderate = (float) (harq_process->R) /(float) 2048; - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) + if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; + kc = 52; if (Coderate < 0.3333){ p_decParams->R = 15; - kc = 52; } else if (Coderate <0.6667){ p_decParams->R = 13; - kc = 32; } else { p_decParams->R = 23; - kc = 17; } } else{ p_decParams->BG = 1; + kc = 68; if (Coderate < 0.6667){ p_decParams->R = 13; - kc = 68; } else if (Coderate <0.8889){ p_decParams->R = 23; - kc = 35; } else { p_decParams->R = 89; - kc = 27; } } if (harq_process->round == 0) { // This is a new packet, so compute quantities regarding segmentation - if (A > 3824) + if (A > NR_MAX_PDSCH_TBS) harq_process->B = A+24; else harq_process->B = A+16; @@ -949,7 +890,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, 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; @@ -967,15 +907,15 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, 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 - printf("Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + LOG_D(PHY,"Segmentation: C %d, K %d\n",harq_process->C,harq_process->K); + notifiedFIFO_elt_t *res_dl; opp_enabled=1; if (harq_process->C>1) { for (int nb_seg =1 ; nb_segC; nb_seg++){ - if ( (res_dl=tryPullTpool(&nf, Tpool_dl)) != NULL ) { + if ( (res_dl=tryPullTpool(&nf, &pool_dl)) != NULL ) { pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl); } @@ -987,16 +927,17 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, memset(&curMsg->proc, 0, sizeof(curMsg->proc)); - curMsg->proc.frame_rx = proc->frame_rx; - curMsg->proc.nr_tti_rx = proc->nr_tti_rx; - curMsg->proc.num_seg = nb_seg; + curMsg->proc.frame_rx = proc->frame_rx; + curMsg->proc.nr_slot_rx = proc->nr_slot_rx; + curMsg->proc.thread_id = proc->thread_id; + curMsg->proc.num_seg = nb_seg; curMsg->proc.eNB_id= eNB_id; curMsg->proc.harq_pid=harq_pid; curMsg->proc.llr8_flag = llr8_flag; - msgToPush_dl->key= (nr_tti_rx%2) ? (nb_seg+30): nb_seg; - pushTpool(Tpool_dl, msgToPush_dl); + msgToPush_dl->key= (nr_slot_rx%2) ? (nb_seg+30): nb_seg; + pushTpool(&pool_dl, msgToPush_dl); /*Qm= harq_process->Qm; Nl=harq_process->Nl; @@ -1023,7 +964,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, Kr = harq_process->K; Kr_bytes = Kr>>3; - K_bytes_F = Kr_bytes-(harq_process->F>>3); + K_bits_F = Kr-harq_process->F; E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); @@ -1040,10 +981,9 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, harq_process->w[r], dlsch_llr+r_offset); -#ifdef DEBUG_DLSCH_DECODING + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) for (int i =0; i<16; i++) - printf("rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); -#endif + LOG_D(PHY,"rx output deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -1053,8 +993,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, start_meas(dlsch_rate_unmatching_stats); #endif -#ifdef DEBUG_DLSCH_DECODING - LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G, Kr*3, harq_process->TBS, @@ -1063,7 +1003,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, harq_process->Nl, harq_process->rvidx, harq_process->round); -#endif + // for tbslbrm calculation according to 5.4.2.1 of 38.212 if (harq_process->Nl < Nl) @@ -1095,37 +1035,30 @@ uint32_t nr_dlsch_decoding_mthread(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); - - //r_offset += E; - //printf("main thread r_offset %d\n",r_offset); -#ifdef DEBUG_DLSCH_DECODING + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) for (int i =0; i<16; i++) - printf("rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset); -#endif + LOG_I(PHY,"rx output ratematching d[%d]= %d r_offset %u\n", i,harq_process->d[r][i], r_offset); -#ifdef DEBUG_DLSCH_DECODING + + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + { if (r==0) { - write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - write_output("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); + LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); + LOG_M("decoder_in.m","dec",&harq_process->d[0][96],(3*8*Kr_bytes)+12,1,0); } - printf("decoder input(segment %u) :",r); + LOG_D(PHY,"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"); -#endif + LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]); + LOG_D(PHY,"\n"); + } - - // printf("Clearing c, %p\n",harq_process->c[r]); memset(harq_process->c[r],0,Kr_bytes); - // printf("done\n"); if (harq_process->C == 1){ - if (A > 3824) + if (A > NR_MAX_PDSCH_TBS) crc_type = CRC24_A; else crc_type = CRC16; @@ -1149,30 +1082,22 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, #if UE_TIMING_TRACE start_meas(dlsch_turbo_decoding_stats); #endif - LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_tti_rx,r,harq_process->C-1); + LOG_D(PHY,"mthread AbsSubframe %d.%d Start LDPC segment %d/%d \n",frame%1024,nr_slot_rx,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)); - - - 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])); - } - - 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])); - } - - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + //set first 2*Z_c bits to zeros + memset(&z[0],0,2*harq_process->Z*sizeof(int16_t)); + //set Filler bits + memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t)); + //Move coded bits before filler bits + memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t)); + //skip filler bits + memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t)); + //Saturate coded bits before decoding into 8 bits values + for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } @@ -1193,11 +1118,11 @@ 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 %u CRC OK\n",r); + LOG_D(PHY,"Segment %u CRC OK\n",r); ret = 2; } else { - printf("CRC NOK\n"); + LOG_D(PHY,"CRC NOK\n"); ret = 1+dlsch->max_ldpc_iterations; } @@ -1205,9 +1130,6 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, printf("Error number of iteration LPDC %d %ld/%ld \n", no_iteration_ldpc, nb_error_decod,nb_total_decod);fflush(stdout); } - //else - //printf("OK number of iteration LPDC %d\n", no_iteration_ldpc); - for (int m=0; m < Kr>>3; m ++) { harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; @@ -1229,10 +1151,10 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, //printf("output channel 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]); //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]); -#ifdef DEBUG_DLSCH_DECODING - for (int k=0;k<32;k++) - printf("output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + for (int k=0;k<32;k++) + LOG_D(PHY,"output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); + #if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); @@ -1241,48 +1163,36 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if ((err_flag == 0) && (ret>=(1+dlsch->max_ldpc_iterations))) {// 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); + LOG_D(PHY,"AbsSubframe %d.%d CRC failed, segment %d/%d \n",frame%1024,nr_slot_rx,r,harq_process->C-1); err_flag = 1; } //} //loop r - int32_t frame_rx_prev = frame; - int32_t tti_rx_prev = nr_tti_rx - 1; - if (tti_rx_prev < 0) { - frame_rx_prev--; - tti_rx_prev += 10*frame_parms->ttis_per_subframe; - } - frame_rx_prev = frame_rx_prev%1024; - if (err_flag == 1) { -#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 + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + 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", + phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); 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++; - - // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); if (harq_process->round >= dlsch->Mlimit) { harq_process->status = SCH_IDLE; harq_process->round = 0; } if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->status,harq_process->round,dlsch->Mlimit,harq_process->TBS); } return((1+dlsch->max_ldpc_iterations)); } else { -#if UE_DEBUG_TRACE - 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 + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d\n", + phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); harq_process->status = SCH_IDLE; harq_process->round = 0; @@ -1294,7 +1204,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, if(is_crnti) { - LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_ue->Mod_id,nr_slot_rx,harq_pid,harq_process->round,harq_process->TBS); } //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); @@ -1336,15 +1246,16 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, 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 %u : Kr= %u bytes\n",r,Kr_bytes); - printf("copied %d bytes to b sequence (harq_pid %d)\n", - (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); - printf("b[0] = %x,c[%d] = %x\n", - harq_process->b[offset], - harq_process->F>>3, - harq_process->c[r]); -#endif + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + { + LOG_I(PHY,"Segment %u : Kr= %u bytes\n",r,Kr_bytes); + LOG_I(PHY,"copied %d bytes to b sequence (harq_pid %d)\n", + (Kr_bytes - (harq_process->F>>3)-((harq_process->C>1)?3:0)),harq_pid); + LOG_I(PHY,"b[0] = %p,c[%d] = %p\n", + (void *)(uint64_t)(harq_process->b[offset]), + harq_process->F>>3, + (void *)(uint64_t)(harq_process->c[r])); + } } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_SEGMENTATION, VCD_FUNCTION_OUT); @@ -1355,15 +1266,14 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, return(ret); } -#endif -#ifdef UE_DLSCH_PARALLELISATION + + void nr_dlsch_decoding_process(void *arg) { nr_rxtx_thread_data_t *rxtxD= (nr_rxtx_thread_data_t *)arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *phy_vars_ue = rxtxD->UE; - NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; int llr8_flag1; int32_t no_iteration_ldpc,length_dec; t_nrLDPC_dec_params decParams; @@ -1377,7 +1287,7 @@ void nr_dlsch_decoding_process(void *arg) //__m128i l; //int16_t inv_d [68*384]; //int16_t *p_invd =&inv_d; - uint8_t kb, kc; + uint8_t kc; uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; uint16_t nb_rb = 30; //to update @@ -1387,13 +1297,11 @@ void nr_dlsch_decoding_process(void *arg) uint16_t length_dmrs = 1; uint32_t i,j; - uint32_t k; - __m128i *pv = (__m128i*)&z; __m128i *pl = (__m128i*)&l; proc->instance_cnt_dlsch_td=-1; - //proc->nr_tti_rx=proc->sub_frame_start; + //proc->nr_slot_rx = proc->sub_frame_start * frame_parms->slots_per_subframe; proc->decoder_thread_available = 1; @@ -1405,8 +1313,10 @@ void nr_dlsch_decoding_process(void *arg) #endif uint32_t A,E; uint32_t G; - uint32_t ret,offset; - uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bytes_F; + + uint32_t ret; + uint32_t r,r_offset=0,Kr,Kr_bytes,err_flag=0,K_bits_F; + uint8_t crc_type; uint8_t C,Cprime; uint8_t Qm; @@ -1417,31 +1327,17 @@ 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; - NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[slot]][eNB_id][0]; + NR_UE_DLSCH_t *dlsch = phy_vars_ue->dlsch[proc->thread_id][eNB_id][0]; NR_DL_UE_HARQ_t *harq_process = dlsch->harq_processes[harq_pid]; - short *dlsch_llr = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[slot]][eNB_id]->llr[0]; - //printf("2thread0 llr flag %d tdp flag %d\n",llr8_flag1, tdp->llr8_flag); + short *dlsch_llr = phy_vars_ue->pdsch_vars[proc->thread_id][eNB_id]->llr[0]; + 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 %u nb symb %d \n", frame, proc->nr_tti_rx, proc->num_seg, r, harq_process->nb_symbols); + LOG_D(PHY,"dlsch decoding process frame %d slot %d segment %d r %u nb symb %d \n", frame, proc->nr_slot_rx, proc->num_seg, r, harq_process->nb_symbols); - /* - if (nb_rb > frame_parms->N_RB_DL) { - printf("dlsch_decoding.c: Illegal nb_rb %d\n",nb_rb); - return(max_ldpc_iterations); - }*/ - - /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]]; - if (harq_pid >= 8) { - printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid); - return(max_ldpc_iterations); - } - */ - nb_rb = harq_process->nb_rb; harq_process->trials[harq_process->round]++; @@ -1465,42 +1361,38 @@ void nr_dlsch_decoding_process(void *arg) else Coderate = (float) (harq_process->R) /(float) 2048; - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25) + if ((A <= 292) || ((A <= NR_MAX_PDSCH_TBS) && (Coderate <= 0.6667)) || Coderate <= 0.25) { p_decParams->BG = 2; + kc = 52; if (Coderate < 0.3333){ p_decParams->R = 15; - kc = 52; } else if (Coderate <0.6667){ p_decParams->R = 13; - kc = 32; } else { p_decParams->R = 23; - kc = 17; } } else{ p_decParams->BG = 1; + kc = 68; if (Coderate < 0.6667){ p_decParams->R = 13; - kc = 68; } else if (Coderate <0.8889){ p_decParams->R = 23; - kc = 35; } else { p_decParams->R = 89; - kc = 27; } } harq_process->round =0; // if (harq_process->round == 0) { // This is a new packet, so compute quantities regarding segmentation - if (A > 3824) + if (A > NR_MAX_PDSCH_TBS) harq_process->B = A+24; else harq_process->B = A+16; @@ -1518,36 +1410,13 @@ void nr_dlsch_decoding_process(void *arg) // } - //printf("round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG); + LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG); p_decParams->numMaxIter = dlsch->max_ldpc_iterations; p_decParams->outMode= 0; - /* - else { - printf("dlsch_decoding.c: Ndi>0 not checked yet!!\n"); - return(max_ldpc_iterations); - } - */ err_flag = 0; - //r_offset = 0; - - /* - uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS; //number of segments to be allocated - - if (nb_rb != 273) { - a_segments = a_segments*nb_rb; - a_segments = a_segments/273 +1; - } - - 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 - printf("Segmentation: C %d, Cminus %d, Kminus %d, Kplus %d\n",harq_process->C,harq_process->Cminus,harq_process->Kminus,harq_process->Kplus); -#endif opp_enabled=1; @@ -1562,9 +1431,7 @@ void nr_dlsch_decoding_process(void *arg) r_offset = Nl*Qm*(G/(Nl*Qm*Cprime)); else r_offset = Nl*Qm*((G/(Nl*Qm*Cprime))+1); - - // printf("thread0 r_offset %d\n",r_offset); - + //for (r=(harq_process->C/2); rC; r++) { // r=1; //(harq_process->C/2); @@ -1572,7 +1439,7 @@ void nr_dlsch_decoding_process(void *arg) Kr = harq_process->K; Kr_bytes = Kr>>3; - K_bytes_F = Kr_bytes-(harq_process->F>>3); + K_bits_F = Kr-harq_process->F; E = nr_get_E(G, harq_process->C, harq_process->Qm, harq_process->Nl, r); @@ -1584,10 +1451,10 @@ void nr_dlsch_decoding_process(void *arg) harq_process->w[r], dlsch_llr+r_offset); -#ifdef DEBUG_DLSCH_DECODING + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) for (int i =0; i<16; i++) - printf("rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); -#endif + LOG_D(PHY,"rx output thread 0 deinterleaving w[%d]= %d r_offset %u\n", i,harq_process->w[r][i], r_offset); + #if UE_TIMING_TRACE stop_meas(dlsch_deinterleaving_stats); @@ -1597,8 +1464,8 @@ void nr_dlsch_decoding_process(void *arg) start_meas(dlsch_rate_unmatching_stats); #endif -#ifdef DEBUG_DLSCH_DECODING - LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + LOG_I(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", harq_pid,r, G, Kr*3, harq_process->TBS, @@ -1607,7 +1474,7 @@ void nr_dlsch_decoding_process(void *arg) harq_process->Nl, harq_process->rvidx, harq_process->round); -#endif + if (Nl<4) Tbslbrm = nr_compute_tbslbrm(harq_process->mcs_table,nb_rb,Nl); @@ -1638,29 +1505,18 @@ void nr_dlsch_decoding_process(void *arg) #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); - - //r_offset += E; - -#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); + if (LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) { + LOG_D(PHY,"decoder input(segment %u) :",r); + for (int i=0;i<(3*8*Kr_bytes)+12;i++) + LOG_D(PHY,"%d : %d\n",i,harq_process->d[r][i]); + LOG_D(PHY,"\n"); } - printf("decoder input(segment %u) :",r); - int i; for (i=0;i<(3*8*Kr_bytes)+12;i++) - printf("%d : %d\n",i,harq_process->d[r][i]); - printf("\n"); -#endif - - // printf("Clearing c, %p\n",harq_process->c[r]); memset(harq_process->c[r],0,Kr_bytes); if (harq_process->C == 1){ - if (A > 3824) + if (A > NR_MAX_PDSCH_TBS) crc_type = CRC24_A; else crc_type = CRC16; @@ -1674,41 +1530,34 @@ void nr_dlsch_decoding_process(void *arg) if (err_flag == 0) { /* - 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", + 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); */ if (llr8_flag1) { - AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", + AssertFatal (Kr >= 256, "LDPC algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n", Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); } #if UE_TIMING_TRACE 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); +// LOG_D(PHY,"AbsSubframe %d.%d Start LDPC 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)); - - 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])); - } - - 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])); - } - - for (i=0, j=0; j < ((kc*p_decParams->Z)>>4); i+=2, j++) + //set first 2*Z_c bits to zeros + memset(&z[0],0,2*harq_process->Z*sizeof(int16_t)); + //set Filler bits + memset((&z[0]+K_bits_F),127,harq_process->F*sizeof(int16_t)); + //Move coded bits before filler bits + memcpy((&z[0]+2*harq_process->Z),harq_process->d[r],(K_bits_F-2*harq_process->Z)*sizeof(int16_t)); + //skip filler bits + memcpy((&z[0]+Kr),harq_process->d[r]+(Kr-2*harq_process->Z),(kc*harq_process->Z-Kr)*sizeof(int16_t)); + //Saturate coded bits before decoding into 8 bits values + for (i=0, j=0; j < ((kc*harq_process->Z)>>4)+1; i+=2, j++) { pl[j] = _mm_packs_epi16(pv[i],pv[i+1]); } @@ -1731,33 +1580,17 @@ void nr_dlsch_decoding_process(void *arg) if (no_iteration_ldpc > 10) 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); + for (int m=0; m < Kr>>3; m ++) { harq_process->c[r][m]= (uint8_t) llrProcBuf[m]; } - /*for (int u=0; u < Kr>>3; u ++) - { - ullrProcBuf[u]= (uint8_t) llrProcBuf[u]; - } + if ( LOG_DEBUGFLAG(DEBUG_DLSCH_DECOD)) + for (int k=0;k<2;k++) + LOG_D(PHY,"segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); - - printf("output unsigned ullrProcBuf \n"); - - for (int j=0; j < Kr>>3; j ++) - { - - printf(" %d \n", ullrProcBuf[j]); - - } - printf(" \n");*/ -#ifdef DEBUG_DLSCH_DECODING - for (int k=0;k<2;k++) - printf("segment 1 output decoder [%d] = 0x%02x \n", k, harq_process->c[r][k]); -#endif #if UE_TIMING_TRACE stop_meas(dlsch_turbo_decoding_stats); @@ -1776,13 +1609,12 @@ void nr_dlsch_decoding_process(void *arg) void *dlsch_thread(void *arg) { //this thread should be over the processing thread to keep in real time - PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; notifiedFIFO_t nf; initNotifiedFIFO(&nf); notifiedFIFO_elt_t *res_dl; initNotifiedFIFO_nothreadSafe(&freeBlocks_dl); - for (int i=0; i= RX_NB_TH_DL) { - if ( (res=tryPullTpool(&nf, Tpool_dl)) != NULL ) { - nr_rxtx_thread_data_t *tmp=(nr_rxtx_thread_data_t *)res->msgData; + while (nbDlProcessing >= tpool_nbthreads(pool_dl)) { + if ( (res=tryPullTpool(&nf, &pool_dl)) != NULL ) { //nbDlProcessing--; pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res); } @@ -1800,7 +1631,7 @@ void *dlsch_thread(void *arg) { usleep(200); } - res_dl=pullTpool(&nf, Tpool_dl); + res_dl=pullTpool(&nf, &pool_dl); nbDlProcessing--; pushNotifiedFIFO_nothreadSafe(&freeBlocks_dl,res_dl); @@ -1813,4 +1644,4 @@ void *dlsch_thread(void *arg) { return NULL; } -#endif + diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index e8204ad0b5..9a31257244 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -37,7 +37,10 @@ //#include "extern.h" #include "PHY/sse_intrin.h" #include "T.h" +#include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" +#include "PHY/NR_REFSIG/nr_refsig.h" +#include "PHY/NR_REFSIG/dmrs_nr.h" #ifndef USER_MODE #define NOCYGWIN_STATIC static @@ -99,17 +102,41 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint16_t length, int16_t **llr_layers); + +/* compute LLR */ +static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, + NR_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp_ptr, + int32_t **dl_ch_mag_ptr, + NR_DL_UE_HARQ_t *dlsch0_harq, + NR_DL_UE_HARQ_t *dlsch1_harq, + RX_type_t rx_type, + unsigned char harq_pid, + unsigned char gNB_id, + unsigned char eNB_id_i, + unsigned char first_symbol_flag, + unsigned char symbol, + unsigned short nb_rb, + unsigned short round, + int32_t codeword_TB0, + int32_t codeword_TB1, + uint32_t len, + uint8_t nr_slot_rx, + uint8_t beamforming_mode); + +/* Main Function */ 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) + UE_nr_rxtx_proc_t *proc, + PDSCH_t type, + unsigned char gNB_id, + unsigned char eNB_id_i, //if this == ue->n_connected_gNB, we assume MU interference + uint32_t frame, + uint8_t nr_slot_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; @@ -142,51 +169,50 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //to be updated higher layer unsigned short start_rb = 0; unsigned short nb_rb_pdsch = 50; - int16_t *pllr_symbol_cw0; - int16_t *pllr_symbol_cw1; - int16_t *pllr_symbol_layer0; - int16_t *pllr_symbol_layer1; //int16_t *pllr_symbol_cw0_deint; //int16_t *pllr_symbol_cw1_deint; - uint32_t llr_offset_symbol; //uint16_t bundle_L = 2; uint8_t pilots=0; + uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; + uint16_t startSymbIdx=0; + uint16_t nbSymb=0; + uint16_t pduBitmap=0x0; switch (type) { case SI_PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; - dlsch = &ue->dlsch_SI[eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id]; + dlsch = &ue->dlsch_SI[gNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; break; case RA_PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; - dlsch = &ue->dlsch_ra[eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id]; + dlsch = &ue->dlsch_ra[gNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; break; case PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; - dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id]; + dlsch = ue->dlsch[proc->thread_id][gNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; dlsch1_harq = dlsch[1]->harq_processes[harq_pid]; - beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id]; + beamforming_mode = ue->transmission_mode[gNB_id] < 7 ? 0 :ue->transmission_mode[gNB_id]; break; default: - LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type); + LOG_E(PHY, "[UE][FATAL] nr_slot_rx %d: Unknown PDSCH format %d\n", nr_slot_rx, type); return -1; break; } if (dlsch0_harq && dlsch1_harq){ - LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status); + LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_slot_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status); if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status == ACTIVE)){ codeword_TB0 = dlsch0_harq->codeword; @@ -220,7 +246,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return -1; } else { - LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); + LOG_E(PHY,"[UE][FATAL] nr_slot_rx %d: no active DLSCH\n", nr_slot_rx); return(-1); } } else if (dlsch0_harq) { @@ -232,7 +258,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("[DEMOD] I am assuming only TB0 is active\n"); #endif } else { - LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); + LOG_E(PHY,"[UE][FATAL] nr_slot_rx %d: no active DLSCH\n", nr_slot_rx); return (-1); } } else { @@ -242,6 +268,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); + if (dlsch0_harq->Qm == 0 || dlsch0_harq->R == 0) { + LOG_W(MAC, "Invalid code rate or Mod order, likely due to unexpected DL DCI.\n"); + return -1; + } #ifdef DEBUG_HARQ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode); @@ -255,8 +285,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, round = dlsch0_harq->round; //printf("round = %d\n", round); - if (eNB_id > 2) { - LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id); + if (gNB_id > 2) { + LOG_W(PHY, "In %s: Illegal gNB_id %d\n", __FUNCTION__, gNB_id); return(-1); } @@ -308,33 +338,33 @@ 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]); + start_meas(&ue->generic_stat_bis[proc->thread_id][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, + nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + pdsch_vars[gNB_id]->dl_ch_estimates, + pdsch_vars[gNB_id]->rxdataF_ext, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id]->pmi_ext, + pdsch_vars[gNB_id]->pmi_ext, symbol, pilots, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_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;rbpmi_ext[rb]); + printf("%d",pdsch_vars[gNB_id]->pmi_ext[rb]); printf("\n"); #endif if (rx_type >= rx_IC_single_stream) { - if (eNB_id_in_connected_eNB) // we are in TM5 - 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, + if (eNB_id_i < ue->n_connected_gNB) // we are in TM5 + nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + pdsch_vars[gNB_id]->dl_ch_estimates, pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, @@ -343,13 +373,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pilots, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); else - 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, + nb_rb = nr_dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + pdsch_vars[gNB_id]->dl_ch_estimates, pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, @@ -358,79 +388,82 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pilots, start_rb, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, frame_parms, dlsch0_harq->mimo_mode); } } else if (beamforming_mode==0) { //else if nb_antennas_ports_gNB==1 && beamforming_mode == 0 - //printf("start nr dlsch extract nr_tti_rx %d thread id %d \n", nr_tti_rx, ue->current_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, + //printf("start nr dlsch extract nr_slot_rx %d thread id %d \n", nr_slot_rx, proc->thread_id); + nb_rb = nr_dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, + pdsch_vars[gNB_id]->dl_ch_estimates, + pdsch_vars[gNB_id]->rxdataF_ext, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, dlsch0_harq->pmi_alloc, - pdsch_vars[eNB_id]->pmi_ext, + pdsch_vars[gNB_id]->pmi_ext, symbol, pilots, - start_rb, + config_type, + start_rb + dlsch0_harq->BWPStart, nb_rb_pdsch, - nr_tti_rx, + nr_slot_rx, ue->high_speed_flag, - frame_parms); + frame_parms, + dlsch0_harq->dlDmrsSymbPos); } /*else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); }*/ - //printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id); + //printf("nb_rb = %d, gNB_id %d\n",nb_rb,gNB_id); if (nb_rb==0) { LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); return(-1); } - len = (pilots==1)? (nb_rb*6):(nb_rb*12); - + len = (pilots==1)? ((config_type==pdsch_dmrs_type1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12); + #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X printf("[AbsSFN %u.%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)); + frame,nr_slot_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else LOG_I(PHY, "[AbsSFN %u.%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)); + frame,nr_slot_rx,slot,symbol,ue->high_speed_flag,type,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif n_tx = frame_parms->nb_antenna_ports_gNB; n_rx = frame_parms->nb_antennas_rx; - nr_dlsch_scale_channel(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext, frame_parms, dlsch, symbol, pilots, + len, nb_rb); #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif if (first_symbol_flag==1) { if (beamforming_mode==0){ if (dlsch0_harq->mimo_modedl_ch_estimates_ext, + nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext, frame_parms, avg, symbol, @@ -441,11 +474,11 @@ 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)+3; + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { - nr_dlsch_channel_level_median(pdsch_vars[eNB_id]->dl_ch_estimates_ext, + nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext, median, n_tx, n_rx, @@ -460,16 +493,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } } - pdsch_vars[eNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; // this might need to be tuned + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; // this might need to be tuned } } //#ifdef UE_DEBUG_TRACE LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", - frame%1024,nr_tti_rx, pdsch_vars[eNB_id]->log2_maxh, - pdsch_vars[eNB_id]->log2_maxh0, - pdsch_vars[eNB_id]->log2_maxh1, - avg[0],avgs); + frame%1024, + nr_slot_rx, + pdsch_vars[gNB_id]->log2_maxh, + pdsch_vars[gNB_id]->log2_maxh0, + pdsch_vars[gNB_id]->log2_maxh1, + avg[0], + avgs); //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode); //#endif @@ -489,46 +525,47 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if T_TRACER if (type == PDSCH) { - T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), + T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_slot_rx), T_INT(avg[0]), T_INT(avg[1]), T_INT(avg[2]), T_INT(avg[3])); } #endif #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_tti_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,nr_slot_rx,slot,symbol,first_symbol_flag,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif // Now channel compensation if (dlsch0_harq->mimo_moderxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - pdsch_vars[eNB_id]->rxdataF_comp0, - (aatx>1) ? pdsch_vars[eNB_id]->rho : NULL, + nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_magr0, + pdsch_vars[gNB_id]->rxdataF_comp0, + (aatx>1) ? pdsch_vars[gNB_id]->rho : NULL, frame_parms, symbol, pilots, first_symbol_flag, dlsch0_harq->Qm, nb_rb, - pdsch_vars[eNB_id]->log2_maxh, + pdsch_vars[gNB_id]->log2_maxh, measurements); // log2_maxh+I0_shift /*if (symbol == 5) { - write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[gNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } */ /*if ((rx_type==rx_IC_single_stream) && - (eNB_id_in_connected_eNB)) { + (eNB_id_in_connected_gNB)) { nr_dlsch_channel_compensation(pdsch_vars[eNB_id_i]->rxdataF_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, pdsch_vars[eNB_id_i]->dl_ch_mag0, @@ -540,11 +577,11 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, first_symbol_flag, i_mod, nb_rb, - pdsch_vars[eNB_id]->log2_maxh, + pdsch_vars[gNB_id]->log2_maxh, measurements); // log2_maxh+I0_shift #ifdef DEBUG_PHY if (symbol == 5) { - write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); + write_output("rxF_comp_d.m","rxF_c_d",&pdsch_vars[gNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); write_output("rxF_comp_i.m","rxF_c_i",&pdsch_vars[eNB_id_i]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1); } #endif @@ -552,99 +589,99 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch_dual_stream_correlation(frame_parms, symbol, nb_rb, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, pdsch_vars[eNB_id_i]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->log2_maxh); + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->log2_maxh); }*/ } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ - nr_dlsch_channel_compensation_core(pdsch_vars[eNB_id]->rxdataF_ext, - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - pdsch_vars[eNB_id]->rxdataF_comp0, //rxdataF_comp - NULL, - n_tx, - n_rx, - dlsch0_harq->Qm, - pdsch_vars[eNB_id]->log2_maxh, - 2*len, // subcarriers Re Im - 0); // we start from the beginning of the vector + nr_dlsch_channel_compensation_core(pdsch_vars[gNB_id]->rxdataF_ext, + pdsch_vars[gNB_id]->dl_ch_estimates_ext, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->rxdataF_comp0, //rxdataF_comp + NULL, + n_tx, + n_rx, + dlsch0_harq->Qm, + pdsch_vars[gNB_id]->log2_maxh, + 2*len, // subcarriers Re Im + 0); // we start from the beginning of the vector /* if (symbol == 5) { - write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[eNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[eNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM + write_output("rxF_comp_d00.m","rxF_c_d00",&pdsch_vars[gNB_id]->rxdataF_comp0[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + write_output("rxF_comp_d01.m","rxF_c_d01",&pdsch_vars[gNB_id]->rxdataF_comp0[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rxF_comp_d10.m","rxF_c_d10",&pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rxF_comp_d11.m","rxF_c_d11",&pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM } */ // compute correlation between signal and interference channels (rho12 and rho21) - nr_dlsch_dual_stream_correlation_core(pdsch_vars[eNB_id]->dl_ch_estimates_ext, - &(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - n_tx, - n_rx, - pdsch_vars[eNB_id]->log2_maxh, - 2*len, - 0); - //printf("rho stream1 =%d\n", &pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round] ); - nr_dlsch_dual_stream_correlation_core(&(pdsch_vars[eNB_id]->dl_ch_estimates_ext[2]), - pdsch_vars[eNB_id]->dl_ch_estimates_ext, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - n_tx, - n_rx, - pdsch_vars[eNB_id]->log2_maxh, - 2*len, - 0); - // printf("rho stream2 =%d\n",&pdsch_vars[eNB_id]->dl_ch_rho2_ext ); - //printf("TM3 log2_maxh : %d\n",pdsch_vars[eNB_id]->log2_maxh); + nr_dlsch_dual_stream_correlation_core(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + &(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]), + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + n_tx, + n_rx, + pdsch_vars[gNB_id]->log2_maxh, + 2*len, + 0); + //printf("rho stream1 =%d\n", &pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round] ); + nr_dlsch_dual_stream_correlation_core(&(pdsch_vars[gNB_id]->dl_ch_estimates_ext[2]), + pdsch_vars[gNB_id]->dl_ch_estimates_ext, + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + n_tx, + n_rx, + pdsch_vars[gNB_id]->log2_maxh, + 2*len, + 0); + // printf("rho stream2 =%d\n",&pdsch_vars[gNB_id]->dl_ch_rho2_ext ); + //printf("TM3 log2_maxh : %d\n",pdsch_vars[gNB_id]->log2_maxh); /* if (symbol == 5) { - write_output("rho0_0.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - write_output("rho2_0.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rho0_1.m.m","rho0_1",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 - write_output("rho2_1.m","rho2_1",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM + write_output("rho0_0.m","rho0_0",&pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + write_output("rho2_0.m","rho2_0",&pdsch_vars[gNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rho0_1.m.m","rho0_1",&pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round][1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rho2_1.m","rho2_1",&pdsch_vars[gNB_id]->dl_ch_rho2_ext[1][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be QAM } */ } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,nr_tti_rx,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif // MRC #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #endif if (frame_parms->nb_antennas_rx > 1) { if (dlsch0_harq->mimo_mode == NR_DUALSTREAM){ - nr_dlsch_detection_mrc_core(pdsch_vars[eNB_id]->rxdataF_comp0, - NULL, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - NULL, - NULL, - n_tx, - n_rx, - 2*len, - 0); + nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0, + NULL, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + NULL, + NULL, + n_tx, + n_rx, + 2*len, + 0); /* if (symbol == 5) { - write_output("rho0_mrc.m","rho0_0",&pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM - write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 + write_output("rho0_mrc.m","rho0_0",&pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round][0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);// should be QAM + write_output("rho2_mrc.m","rho2_0",&pdsch_vars[gNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 } */ } } //printf("start compute LLR\n"); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { - rxdataF_comp_ptr = pdsch_vars[eNB_id]->rxdataF_comp1[harq_pid][round]; - dl_ch_mag_ptr = pdsch_vars[eNB_id]->dl_ch_mag1[harq_pid][round]; + rxdataF_comp_ptr = pdsch_vars[gNB_id]->rxdataF_comp1[harq_pid][round]; + dl_ch_mag_ptr = pdsch_vars[gNB_id]->dl_ch_mag1[harq_pid][round]; } else { rxdataF_comp_ptr = pdsch_vars[eNB_id_i]->rxdataF_comp0; @@ -653,390 +690,88 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif #if UE_TIMING_TRACE - start_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][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 + /* Store the valid DL RE's */ + pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = len; - if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0; - llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1]; - //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0]; - //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1]; - pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0]; - pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1]; - pllr_symbol_layer0 += llr_offset_symbol; - pllr_symbol_layer1 += llr_offset_symbol; - pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0]; - pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1]; - pllr_symbol_cw0 += llr_offset_symbol; - pllr_symbol_cw1 += llr_offset_symbol; - - pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol; - - /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", - symbol, - nb_rb,dlsch0_harq->Qm, - pdsch_vars[eNB_id]->llr_length[symbol], - pdsch_vars[eNB_id]->llr_offset[symbol], - (int16_t*)pdsch_vars[eNB_id]->llr[0], - pllr_symbol_cw0);*/ - - /*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", - symbol, - nb_rb,dlsch0_harq->Qm, - pdsch_vars[eNB_id]->llr_length[symbol], - pdsch_vars[eNB_id]->llr_offset[symbol], - pdsch_vars[eNB_id]->llr[0], - pllr_symbol_cw0);*/ - - switch (dlsch0_harq->Qm) { - case 2 : - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - symbol, - len, - first_symbol_flag, - nb_rb, - beamforming_mode); - - } else if (codeword_TB0 == -1){ - - nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pllr_symbol_cw1, - symbol, - len, - first_symbol_flag, - nb_rb, - beamforming_mode); + if(dlsch0_harq->status == ACTIVE) { + startSymbIdx = dlsch0_harq->start_symbol; + nbSymb = dlsch0_harq->nb_symbols; + pduBitmap = dlsch0_harq->pduBitmap; } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - nr_dlsch_qpsk_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_qpsk_qpsk_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - nr_dlsch_qpsk_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_16qam_qpsk_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } + if(dlsch1_harq) { + startSymbIdx = dlsch1_harq->start_symbol; + nbSymb = dlsch1_harq->nb_symbols; + pduBitmap = dlsch1_harq->pduBitmap; + } + + /* Check for PTRS bitmap and process it respectively */ + if((pduBitmap & 0x1) && (type == PDSCH)) { + nr_pdsch_ptrs_processing(ue, + pdsch_vars, + frame_parms, + dlsch0_harq, + dlsch1_harq, + gNB_id, + nr_slot_rx, + symbol, + (nb_rb*12), + harq_pid, + dlsch[0]->rnti,rx_type); + pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; + } + + /* at last symbol in a slot calculate LLR's for whole slot */ + if(symbol == (startSymbIdx + nbSymb -1)) { + for(uint8_t i =startSymbIdx; i <= nbSymb;i++) { + /* re evaluating the first symbol flag as LLR's are done in symbol loop */ + if(i == startSymbIdx && i < 3) { + first_symbol_flag =1; } else { - nr_dlsch_qpsk_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_64qam_qpsk_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - } - break; - case 4 : - if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) { - nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[eNB_id]->llr128, - beamforming_mode); - } else if (codeword_TB0 == -1){ - nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[1], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[eNB_id]->llr128_2ndstream, - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - nr_dlsch_16qam_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_qpsk_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - nr_dlsch_16qam_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_16qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else { - nr_dlsch_16qam_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_64qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0, - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); + first_symbol_flag=0; } + /* Calculate LLR's for each symbol */ + nr_dlsch_llr(pdsch_vars, frame_parms, + rxdataF_comp_ptr, dl_ch_mag_ptr, + dlsch0_harq, dlsch1_harq, + rx_type, harq_pid, + gNB_id, eNB_id_i, + first_symbol_flag, + i, nb_rb, round, + codeword_TB0, codeword_TB1, + pdsch_vars[gNB_id]->dl_valid_re[i-1], + nr_slot_rx, beamforming_mode); } } - break; - case 6 : - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[eNB_id]->llr_offset[symbol], - beamforming_mode); - } else if (codeword_TB0 == -1){ - nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pllr_symbol_cw1, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[eNB_id]->llr_offset[symbol], - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - nr_dlsch_64qam_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_qpsk_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - nr_dlsch_64qam_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - pdsch_vars[eNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_16qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[eNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr128_2ndstream); - } - } - else { - nr_dlsch_64qam_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[eNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[eNB_id]->dl_ch_rho2_ext, - (int16_t*)pllr_symbol_layer0, - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr_offset[symbol]); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_64qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[eNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[eNB_id]->dl_ch_mag0,//i - pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round], - pllr_symbol_layer1, - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_tti_rx,symbol), - pdsch_vars[eNB_id]->llr_offset[symbol]); - } - } - } - break; - default: - LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); - return(-1); - break; - } - - if (dlsch1_harq) { - switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) { - case 2 : - if (rx_type==rx_standard) { - nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - symbol,len,first_symbol_flag,nb_rb, - beamforming_mode); - } - break; - case 4: - if (rx_type==rx_standard) { - nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pdsch_vars[eNB_id]->llr[0], - pdsch_vars[eNB_id]->dl_ch_mag0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[eNB_id]->llr128, - beamforming_mode); - } - break; - case 6 : - if (rx_type==rx_standard) { - nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - pdsch_vars[eNB_id]->dl_ch_mag0, - pdsch_vars[eNB_id]->dl_ch_magb0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[eNB_id]->llr_offset[symbol], - beamforming_mode); - } - break; - default: - LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); - return(-1); - break; - } - } //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch); - - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_layer_demapping(pdsch_vars[eNB_id]->llr, - dlsch[0]->harq_processes[harq_pid]->Nl, - dlsch[0]->harq_processes[harq_pid]->Qm, - dlsch[0]->harq_processes[harq_pid]->G, - pdsch_vars[eNB_id]->layer_llr); - } + + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, + dlsch[0]->harq_processes[harq_pid]->Nl, + dlsch[0]->harq_processes[harq_pid]->Qm, + dlsch[0]->harq_processes[harq_pid]->G, + pdsch_vars[gNB_id]->layer_llr); + } #if UE_TIMING_TRACE - stop_meas(&ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_tti_rx,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -1045,33 +780,32 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, char filename[40]; uint8_t aa = 0; - snprintf(filename, 40, "rxdataF0_symb_%d_nr_tti_rx_%d.m", symbol, nr_tti_rx); - write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); + snprintf(filename, 40, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "rxdataF0", &common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); - snprintf(filename, 40, "dl_ch_estimates0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); - write_output(filename, "dl_ch_estimates", &pdsch_vars[eNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); + snprintf(filename, 40, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "dl_ch_estimates", &pdsch_vars[gNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); - snprintf(filename, 40, "rxdataF_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); - write_output(filename, "rxdataF_ext", &pdsch_vars[eNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + snprintf(filename, 40, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "rxdataF_ext", &pdsch_vars[gNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); - snprintf(filename, 40, "dl_ch_estimates_ext0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); - write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[eNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + snprintf(filename, 40, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[gNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); - snprintf(filename, 40, "rxdataF_comp0%d_symb_%d_nr_tti_rx_%d.m", aa, symbol, nr_tti_rx); - write_output(filename, "rxdataF_comp00", &pdsch_vars[eNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + snprintf(filename, 40, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "rxdataF_comp00", &pdsch_vars[gNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); for (int i=0; i < 2; i++){ - snprintf(filename, 40, "llr%d_symb_%d_nr_tti_rx_%d.m", i, symbol, nr_tti_rx); - write_output(filename,"llr", &pdsch_vars[eNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0); + snprintf(filename, 40, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx); + write_output(filename,"llr", &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm), 1, 0); } #endif #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(T_UE_PHY_PDSCH_IQ, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame%1024), + T_INT(nr_slot_rx), T_INT(nb_rb), 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_slot*2)); + T_BUFFER(&pdsch_vars[gNB_id]->rxdataF_comp0[gNB_id][0], 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); @@ -1132,6 +866,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, int **dl_ch_estimates_ext, int **dl_ch_mag, int **dl_ch_magb, + int **dl_ch_magr, int **rxdataF_comp, int **rho, NR_DL_FRAME_PARMS *frame_parms, @@ -1148,17 +883,23 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, unsigned short rb; unsigned char aatx,aarx; - __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r; QAM_amp128b = _mm_setzero_si128(); for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) QAM_amp128b = _mm_setzero_si128(); + QAM_amp128r = _mm_setzero_si128(); } else if (mod_order == 6) { QAM_amp128 = _mm_set1_epi16(QAM64_n1); // QAM_amp128b = _mm_set1_epi16(QAM64_n2); + QAM_amp128r = _mm_setzero_si128(); + } else if (mod_order == 8) { + QAM_amp128 = _mm_set1_epi16(QAM256_n1); + QAM_amp128b = _mm_set1_epi16(QAM256_n2); + QAM_amp128r = _mm_set1_epi16(QAM256_n3); } // printf("comp: rxdataF_comp %p, symbol %d\n",rxdataF_comp[0],symbol); @@ -1168,6 +909,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch128 = (__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; dl_ch_mag128 = (__m128i *)&dl_ch_mag[(aatx<<1)+aarx][symbol*nb_rb*12]; dl_ch_mag128b = (__m128i *)&dl_ch_magb[(aatx<<1)+aarx][symbol*nb_rb*12]; + dl_ch_mag128r = (__m128i *)&dl_ch_magr[(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]; @@ -1188,6 +930,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[0] = dl_ch_mag128[0]; + dl_ch_mag128r[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); //print_ints("Re(ch):",(int16_t*)&mmtmpD0); @@ -1195,6 +938,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); dl_ch_mag128[1] = _mm_unpackhi_epi16(mmtmpD0,mmtmpD0); dl_ch_mag128b[1] = dl_ch_mag128[1]; + dl_ch_mag128r[1] = dl_ch_mag128[1]; dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); @@ -1205,6 +949,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); dl_ch_mag128b[2] = dl_ch_mag128[2]; + dl_ch_mag128r[2] = dl_ch_mag128[2]; dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); @@ -1217,9 +962,18 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); + dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); + dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); + + dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); + dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); + if (pilots==0) { dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + + dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); + dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); } } @@ -1287,12 +1041,14 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch128+=3; dl_ch_mag128+=3; dl_ch_mag128b+=3; + dl_ch_mag128r+=3; rxdataF128+=3; rxdataF_comp128+=3; } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less dl_ch128+=2; dl_ch_mag128+=2; dl_ch_mag128b+=2; + dl_ch_mag128r+=2; rxdataF128+=2; rxdataF_comp128+=2; } @@ -1797,6 +1553,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, NR_UE_DLSCH_t **dlsch_ue, uint8_t symbol, uint8_t pilots, + uint32_t len, unsigned short nb_rb) { @@ -1806,17 +1563,14 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, unsigned char aatx,aarx; __m128i *dl_ch128, ch_amp128; - - if (pilots==1){ - nb_rb = nb_rb>>1; - } + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); // Determine scaling amplitude based the symbol 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); + 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); ch_amp128 = _mm_set1_epi16(ch_amp); // Q3.13 @@ -1825,7 +1579,7 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*nb_rb*12]; - for (rb=0;rb>x; //printf("len = %d = %d * 2^(%d)\n",len,y,x); + AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); + for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) for (aarx=0; aarxnb_antennas_rx; aarx++) { //clear average level @@ -2351,11 +2107,13 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned char *pmi_ext, unsigned char symbol, uint8_t pilots, + uint8_t config_type, unsigned short start_rb, unsigned short nb_rb_pdsch, - unsigned char nr_tti_rx, + unsigned char nr_slot_rx, uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms) { + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos) { @@ -2363,21 +2121,24 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned char i,aarx; //,nsymb,sss_symb,pss_symb=0,l; int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; - + int8_t validDmrsEst = 0; //store last DMRS Symbol index unsigned char j=0; - AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, - "nushift %d is illegal\n",frame_parms->nushift); + if (config_type==pdsch_dmrs_type1) + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 1, + "nushift %d is illegal\n",frame_parms->nushift); + else + AssertFatal(frame_parms->nushift ==0 || frame_parms->nushift == 2 || frame_parms->nushift == 4, + "nushift %d is illegal\n",frame_parms->nushift); for (aarx=0; aarxnb_antennas_rx; aarx++) { k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; - if (high_speed_flag == 1) - dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; - else - dl_ch0 = &dl_ch_estimates[aarx][0]; + validDmrsEst = get_valid_dmrs_idx_for_channel_est(dlDmrsSymbPos,symbol); + + dl_ch0 = &dl_ch_estimates[aarx][(validDmrsEst*(frame_parms->ofdm_symbol_size))]; dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol*(nb_rb_pdsch*12)]; @@ -2388,34 +2149,44 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, if (k>frame_parms->ofdm_symbol_size) { k = k-frame_parms->ofdm_symbol_size; rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; - } + } 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; + } else {//the symbol contains DMRS + j=0; + if (config_type==pdsch_dmrs_type1){ + 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; + } else { + for (i = (2+frame_parms->nushift); i<6; i++) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + for (i = (8+frame_parms->nushift); i<12; i++) { + rxF_ext[j]=rxF[i]; + dl_ch0_ext[j]=dl_ch0[i]; + j++; + } + dl_ch0_ext+= 8; + rxF_ext+= 8; + } } - + 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))]; + k = k-(frame_parms->ofdm_symbol_size); + rxF = &rxdataF[aarx][k+(symbol*(frame_parms->ofdm_symbol_size))]; } } } @@ -2434,7 +2205,7 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, uint8_t pilots, unsigned short start_rb, unsigned short nb_rb_pdsch, - unsigned char nr_tti_rx, + unsigned char nr_slot_rx, uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode) { @@ -2546,99 +2317,516 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, AssertFatal(0, "Not supported number of layers %d\n", Nl); } } + +static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, + NR_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp_ptr, + int32_t **dl_ch_mag_ptr, + NR_DL_UE_HARQ_t *dlsch0_harq, + NR_DL_UE_HARQ_t *dlsch1_harq, + RX_type_t rx_type, + unsigned char harq_pid, + unsigned char gNB_id, + unsigned char eNB_id_i, + unsigned char first_symbol_flag, + unsigned char symbol, + unsigned short nb_rb, + unsigned short round, + int32_t codeword_TB0, + int32_t codeword_TB1, + uint32_t len, + uint8_t nr_slot_rx, + uint8_t beamforming_mode) +{ + + int16_t *pllr_symbol_cw0; + int16_t *pllr_symbol_cw1; + int16_t *pllr_symbol_layer0; + int16_t *pllr_symbol_layer1; + uint32_t llr_offset_symbol; + + if (first_symbol_flag==1) pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0; + llr_offset_symbol = pdsch_vars[gNB_id]->llr_offset[symbol-1]; + //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[gNB_id]->llr[0]; + //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[gNB_id]->llr[1]; + pllr_symbol_layer0 = pdsch_vars[gNB_id]->layer_llr[0]; + pllr_symbol_layer1 = pdsch_vars[gNB_id]->layer_llr[1]; + pllr_symbol_layer0 += llr_offset_symbol; + pllr_symbol_layer1 += llr_offset_symbol; + pllr_symbol_cw0 = pdsch_vars[gNB_id]->llr[0]; + pllr_symbol_cw1 = pdsch_vars[gNB_id]->llr[1]; + pllr_symbol_cw0 += llr_offset_symbol; + pllr_symbol_cw1 += llr_offset_symbol; + + pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol; + + /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", + symbol, + nb_rb,dlsch0_harq->Qm, + pdsch_vars[gNB_id]->llr_length[symbol], + pdsch_vars[gNB_id]->llr_offset[symbol], + (int16_t*)pdsch_vars[gNB_id]->llr[0], + pllr_symbol_cw0);*/ + + /*printf("compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", + symbol, + nb_rb,dlsch0_harq->Qm, + pdsch_vars[gNB_id]->llr_length[symbol], + pdsch_vars[gNB_id]->llr_offset[symbol], + pdsch_vars[gNB_id]->llr[0], + pllr_symbol_cw0);*/ + + switch (dlsch0_harq->Qm) { + case 2 : + if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { + nr_dlsch_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw0, + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); + + } else if (codeword_TB0 == -1){ + + nr_dlsch_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw1, + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); + } + else if (rx_type >= rx_IC_single_stream) { + if (dlsch1_harq->Qm == 2) { + nr_dlsch_qpsk_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_qpsk_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + else if (dlsch1_harq->Qm == 4) { + nr_dlsch_qpsk_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + dl_ch_mag_ptr,//i + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_16qam_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + else { + nr_dlsch_qpsk_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + dl_ch_mag_ptr,//i + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_64qam_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + } + break; + case 4 : + if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) { + nr_dlsch_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pdsch_vars[gNB_id]->llr[0], + pdsch_vars[gNB_id]->dl_ch_mag0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr128, + beamforming_mode); + } else if (codeword_TB0 == -1){ + nr_dlsch_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pdsch_vars[gNB_id]->llr[1], + pdsch_vars[gNB_id]->dl_ch_mag0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr128_2ndstream, + beamforming_mode); + } + else if (rx_type >= rx_IC_single_stream) { + if (dlsch1_harq->Qm == 2) { + nr_dlsch_16qam_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_qpsk_16qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + pdsch_vars[gNB_id]->dl_ch_mag0,//i + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + else if (dlsch1_harq->Qm == 4) { + nr_dlsch_16qam_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_16qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[gNB_id]->dl_ch_mag0,//i + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + else { + nr_dlsch_16qam_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_64qam_16qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0, + dl_ch_mag_ptr, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + } + break; + case 6 : + if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { + nr_dlsch_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + (int16_t*)pllr_symbol_cw0, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr_offset[symbol], + beamforming_mode); + } else if (codeword_TB0 == -1){ + nr_dlsch_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw1, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr_offset[symbol], + beamforming_mode); + } + else if (rx_type >= rx_IC_single_stream) { + if (dlsch1_harq->Qm == 2) { + nr_dlsch_64qam_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_qpsk_64qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + else if (dlsch1_harq->Qm == 4) { + nr_dlsch_64qam_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + pdsch_vars[gNB_id]->layer_llr[0], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_16qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[gNB_id]->dl_ch_mag0,//i + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream); + } + } + else { + nr_dlsch_64qam_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + rxdataF_comp_ptr,//i + pdsch_vars[gNB_id]->dl_ch_mag0, + dl_ch_mag_ptr,//i + pdsch_vars[gNB_id]->dl_ch_rho2_ext, + (int16_t*)pllr_symbol_layer0, + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr_offset[symbol]); + if (rx_type==rx_IC_dual_stream) { + nr_dlsch_64qam_64qam_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0,//i + dl_ch_mag_ptr, + pdsch_vars[gNB_id]->dl_ch_mag0,//i + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pllr_symbol_layer1, + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr_offset[symbol]); + } + } + } + break; + case 8: + if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { + nr_dlsch_256qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + (int16_t*)pllr_symbol_cw0, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_magr0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr_offset[symbol], + beamforming_mode); + } else if (codeword_TB0 == -1){ + nr_dlsch_256qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw1, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_magr0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr_offset[symbol], + beamforming_mode); + } + break; + default: + LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); + return(-1); + break; + } + + if (dlsch1_harq) { + switch (nr_get_Qm_dl(dlsch1_harq->mcs,dlsch1_harq->mcs_table)) { + case 2 : + if (rx_type==rx_standard) { + nr_dlsch_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw0, + symbol,len,first_symbol_flag,nb_rb, + beamforming_mode); + } + break; + case 4: + if (rx_type==rx_standard) { + nr_dlsch_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pdsch_vars[gNB_id]->llr[0], + pdsch_vars[gNB_id]->dl_ch_mag0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr128, + beamforming_mode); + } + break; + case 6 : + if (rx_type==rx_standard) { + nr_dlsch_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw0, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr_offset[symbol], + beamforming_mode); + } + break; + case 8 : + if (rx_type==rx_standard) { + nr_dlsch_256qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0, + pllr_symbol_cw0, + pdsch_vars[gNB_id]->dl_ch_mag0, + pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_magr0, + symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->llr_offset[symbol], + beamforming_mode); + } + break; + default: + LOG_W(PHY,"rx_dlsch.c : Unknown mod_order!!!!\n"); + return(-1); + break; + } + } + return 0; +} //============================================================================================== #ifdef USER_MODE -void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t nr_tti_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) +void dump_dlsch2(PHY_VARS_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid) { unsigned int nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; char fname[32],vname[32]; int N_RB_DL=ue->frame_parms.N_RB_DL; - snprintf(fname, 32, "dlsch%d_rxF_r%d_ext0.m",eNB_id,round); - snprintf(vname, 32, "dl%d_rxF_r%d_ext0",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_rxF_r%d_ext0.m", gNB_id, round); + snprintf(vname, 32, "dl%d_rxF_r%d_ext0", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1); if (ue->frame_parms.nb_antennas_rx >1) { - snprintf(fname, 32, "dlsch%d_rxF_r%d_ext1.m",eNB_id,round); - snprintf(vname, 32, "dl%d_rxF_r%d_ext1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_rxF_r%d_ext1.m", gNB_id, round); + snprintf(vname, 32, "dl%d_rxF_r%d_ext1", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1); } - snprintf(fname, 32, "dlsch%d_ch_r%d_ext00.m",eNB_id,round); - snprintf(vname, 32, "dl%d_ch_r%d_ext00",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_ch_r%d_ext00.m", gNB_id, round); + snprintf(vname, 32, "dl%d_ch_r%d_ext00", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); - if (ue->transmission_mode[eNB_id]==7){ - snprintf(fname, 32, "dlsch%d_bf_ch_r%d.m",eNB_id,round); - snprintf(vname, 32, "dl%d_bf_ch_r%d",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1); - //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1); + if (ue->transmission_mode[gNB_id]==7){ + snprintf(fname, 32, "dlsch%d_bf_ch_r%d.m", gNB_id, round); + snprintf(vname, 32, "dl%d_bf_ch_r%d", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1); + //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[gNB_id]->dl_bf_ch_estimates[0],512,1,1); - snprintf(fname, 32, "dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round); - snprintf(vname, 32, "dl%d_bf_ch_r%d_ext00",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_bf_ch_r%d_ext00.m", gNB_id, round); + snprintf(vname, 32, "dl%d_bf_ch_r%d_ext00", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1); } if (ue->frame_parms.nb_antennas_rx == 2) { - snprintf(fname, 32, "dlsch%d_ch_r%d_ext01.m",eNB_id,round); - snprintf(vname, 32, "dl%d_ch_r%d_ext01",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_ch_r%d_ext01.m", gNB_id, round); + snprintf(vname, 32, "dl%d_ch_r%d_ext01", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); } if (ue->frame_parms.nb_antenna_ports_gNB == 2) { - snprintf(fname, 32, "dlsch%d_ch_r%d_ext10.m",eNB_id,round); - snprintf(vname, 32, "dl%d_ch_r%d_ext10",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_ch_r%d_ext10.m", gNB_id, round); + snprintf(vname, 32, "dl%d_ch_r%d_ext10", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1); if (ue->frame_parms.nb_antennas_rx == 2) { - snprintf(fname, 32, "dlsch%d_ch_r%d_ext11.m",eNB_id,round); - snprintf(vname, 32, "dl%d_ch_r%d_ext11",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_ch_r%d_ext11.m",gNB_id,round); + snprintf(vname, 32, "dl%d_ch_r%d_ext11",gNB_id,round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1); } } - snprintf(fname, 32, "dlsch%d_rxF_r%d_uespec0.m",eNB_id,round); - snprintf(vname, 32, "dl%d_rxF_r%d_uespec0",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1); + snprintf(fname, 32, "dlsch%d_rxF_r%d_uespec0.m", gNB_id, round); + snprintf(vname, 32, "dl%d_rxF_r%d_uespec0", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1); /* - write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); - write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1); - write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1); + write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[gNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1); + write_output("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[gNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1); + write_output("dlsch%d_ch_ext11.m","dl11_ch0_ext",pdsch_vars[gNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1); */ - snprintf(fname, 32, "dlsch%d_r%d_rho.m",eNB_id,round); - snprintf(vname, 32, "dl_rho_r%d_%d",eNB_id,round); + snprintf(fname, 32, "dlsch%d_r%d_rho.m", gNB_id, round); + snprintf(vname, 32, "dl_rho_r%d_%d", gNB_id, round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); - snprintf(fname, 32, "dlsch%d_r%d_rho2.m",eNB_id,round); - snprintf(vname, 32, "dl_rho2_r%d_%d",eNB_id,round); + snprintf(fname, 32, "dlsch%d_r%d_rho2.m", gNB_id, round); + snprintf(vname, 32, "dl_rho2_r%d_%d", gNB_id, round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1); - snprintf(fname, 32, "dlsch%d_rxF_r%d_comp0.m",eNB_id,round); - snprintf(vname, 32, "dl%d_rxF_r%d_comp0",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_rxF_r%d_comp0.m", gNB_id, round); + snprintf(vname, 32, "dl%d_rxF_r%d_comp0", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1); if (ue->frame_parms.nb_antenna_ports_gNB == 2) { - snprintf(fname, 32, "dlsch%d_rxF_r%d_comp1.m",eNB_id,round); - snprintf(vname, 32, "dl%d_rxF_r%d_comp1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_rxF_r%d_comp1.m", gNB_id, round); + snprintf(vname, 32, "dl%d_rxF_r%d_comp1", gNB_id, round); + write_output(fname,vname,ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1); } - snprintf(fname, 32, "dlsch%d_rxF_r%d_llr.m",eNB_id,round); - snprintf(vname, 32, "dl%d_r%d_llr",eNB_id,round); - write_output(fname,vname, ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0); - snprintf(fname, 32, "dlsch%d_r%d_mag1.m",eNB_id,round); - snprintf(vname, 32, "dl%d_r%d_mag1",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1); - snprintf(fname, 32, "dlsch%d_r%d_mag2.m",eNB_id,round); - snprintf(vname, 32, "dl%d_r%d_mag2",eNB_id,round); - write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1); + snprintf(fname, 32, "dlsch%d_rxF_r%d_llr.m", gNB_id, round); + snprintf(vname, 32, "dl%d_r%d_llr", gNB_id, round); + write_output(fname, vname, ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0], coded_bits_per_codeword[0], 1, 0); + snprintf(fname, 32, "dlsch%d_r%d_mag1.m", gNB_id, round); + snprintf(vname, 32, "dl%d_r%d_mag1", gNB_id, round); + write_output(fname, vname, ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_mag0[0], 12*N_RB_DL*nsymb, 1, 1); + snprintf(fname, 32, "dlsch%d_r%d_mag2.m", gNB_id, round); + snprintf(vname, 32, "dl%d_r%d_mag2", gNB_id, round); + write_output(fname, vname, ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_magb0[0], 12*N_RB_DL*nsymb, 1, 1); - // printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh); + // printf("log2_maxh = %d\n",ue->pdsch_vars[gNB_id]->log2_maxh); } #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c index e0b24a033a..68a206e7c7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c @@ -1089,6 +1089,108 @@ void nr_dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms, } } //#endif + +//---------------------------------------------------------------------------------------------- +// 256-QAM +//---------------------------------------------------------------------------------------------- + +void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + int32_t **dl_ch_magr, + uint8_t symbol, + uint32_t len, + uint8_t first_symbol_flag, + uint16_t nb_rb, + uint32_t llr_offset, + uint8_t beamforming_mode) +{ + __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)]; + __m128i *ch_mag,*ch_magb,*ch_magr; + + int i,len2; + unsigned char len_mod4; + short *llr; + int16_t *llr2; + int8_t *pllr_symbol; + + /* + if (first_symbol_flag==1) + llr = dlsch_llr; + else + llr = *llr_save; + */ + llr = dlsch_llr; + + pllr_symbol = (int8_t*)dlsch_llr; + pllr_symbol += llr_offset; + + ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)]; + ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)]; + ch_magr = (__m128i*)&dl_ch_magr[0][(symbol*nb_rb*12)]; + llr2 = llr; + llr += (len*8); + + len_mod4 =len&3; + len2=len>>2; // length in quad words (4 REs) + len2+=((len_mod4==0)?0:1); + + for (i=0; iframe_parms; int ret =-1; @@ -131,7 +131,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini #endif // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf for(int i=pbch_initial_symbol; idlsch_channel_estimation_stats); #endif @@ -155,7 +155,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini #endif // computing channel estimation for selected best ssb for(int i=pbch_initial_symbol; ii_ssb,temp_ptr->n_hf); + nr_pbch_channel_estimation(ue,proc,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); #endif @@ -202,7 +202,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini char duplex_string[2][4] = {"FDD","TDD"}; char prefix_string[2][9] = {"NORMAL","EXTENDED"}; -int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int n_frames) +int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames) { int32_t sync_pos, sync_pos_frame; // k_ssb, N_ssb_crb, sync_pos2, @@ -286,28 +286,29 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, for(int i=0; i<4;i++) nr_slot_fep_init_sync(ue, - i, - 0, - is*fp->samples_per_frame+ue->ssb_offset, - 0); + proc, + i, + 0, + is*fp->samples_per_frame+ue->ssb_offset, + 0); #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"Calling sss detection (normal CP)\n"); #endif - rx_sss_nr(ue,&metric_tdd_ncp,&phase_tdd_ncp); - - //FK: why do we need to do this again here? - //nr_init_frame_parms_ue(fp,NR_MU_1,NORMAL,n_ssb_crb,0); + rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp); nr_gold_pbch(ue); - ret = nr_pbch_detection(proc, ue,1,mode); // start pbch detection at first symbol after pss + ret = nr_pbch_detection(proc, ue, 1); // start pbch detection at first symbol after pss if (ret == 0) { // sync at symbol ue->symbol_offset // computing the offset wrt the beginning of the frame - sync_pos_frame = (fp->ofdm_symbol_size + fp->nb_prefix_samples0)+((ue->symbol_offset)-1)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); - + int mu = fp->numerology_index; + // number of symbols with different prefix length + // every 7*(1<symbol_offset/(7*(1<ofdm_symbol_size + fp->nb_prefix_samples0)+(ue->symbol_offset-n_symb_prefix0)*(fp->ofdm_symbol_size + fp->nb_prefix_samples); if (ue->ssb_offset < sync_pos_frame) ue->rx_offset = fp->samples_per_frame - sync_pos_frame + ue->ssb_offset; else @@ -321,8 +322,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, runmode_t mode, int nb_prefix_samples0 = fp->nb_prefix_samples0; fp->nb_prefix_samples0 = fp->nb_prefix_samples; - nr_slot_fep(ue,0, 0, ue->ssb_offset, 0, NR_PDCCH_EST); - nr_slot_fep(ue,1, 0, ue->ssb_offset, 0, NR_PDCCH_EST); + nr_slot_fep(ue, proc, 0, 0, ue->ssb_offset, 0, NR_PDCCH_EST); + nr_slot_fep(ue, proc, 1, 0, ue->ssb_offset, 0, NR_PDCCH_EST); fp->nb_prefix_samples0 = nb_prefix_samples0; LOG_I(PHY,"[UE %d] AUTOTEST Cell Sync : frame = %d, rx_offset %d, freq_offset %d \n", diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 612dc6283d..e33693ce0e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -35,8 +35,9 @@ #include "PHY/sse_intrin.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/INIT/phy_init.h" +#include "openair1/SCHED_NR_UE/defs.h" -//#define DEBUG_PBCH 1 +//#define DEBUG_PBCH //#define DEBUG_PBCH_ENCODING #ifdef OPENAIR2 @@ -61,7 +62,8 @@ uint16_t nr_pbch_extract(int **rxdataF, int nushiftmod4 = frame_parms->nushift; unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; //and - if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size; + // if (rx_offset>= frame_parms->ofdm_symbol_size) rx_offset-=frame_parms->ofdm_symbol_size; + rx_offset=(rx_offset)%(frame_parms->ofdm_symbol_size); AssertFatal(symbol>=1 && symbol<5, "symbol %d illegal for PBCH extraction\n", @@ -103,8 +105,8 @@ uint16_t nr_pbch_extract(int **rxdataF, j++; } - //rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); - rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); + rx_offset=(rx_offset+1)%(frame_parms->ofdm_symbol_size); + //rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); } rxF_ext+=9; @@ -126,12 +128,14 @@ uint16_t nr_pbch_extract(int **rxdataF, j++; } - //rx_offset=(rx_offset+1)&(frame_parms->ofdm_symbol_size-1); - rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); + rx_offset=(rx_offset+1)%(frame_parms->ofdm_symbol_size); + //rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 1) : (rx_offset+1); } rxF_ext+=9; - } else rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 12) : (rx_offset+12);//rx_offset = (rx_offset+12)&(frame_parms->ofdm_symbol_size-1); + } else{ //rx_offset = (rx_offset >= frame_parms->ofdm_symbol_size) ? (rx_offset - frame_parms->ofdm_symbol_size + 12) : (rx_offset+12); + rx_offset = (rx_offset+12)%(frame_parms->ofdm_symbol_size); + } } } @@ -415,12 +419,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, - uint8_t eNB_id, + uint8_t gNB_id, uint8_t i_ssb, MIMO_mode_t mimo_mode, uint32_t high_speed_flag) { - int Ns = proc->nr_tti_rx; NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars; int max_h=0; int symbol; @@ -454,15 +457,15 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #ifdef DEBUG_PBCH - //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF); + //printf("address dataf %p",nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF); write_output("rxdataF0_pbch.m","rxF0pbch", - &nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); + &nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); #endif // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot for (symbol=1; symbol<4; symbol++) { - nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns]].rxdataF, + nr_pbch_extract(nr_ue_common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF, nr_ue_pbch_vars->dl_ch_estimates, nr_ue_pbch_vars->rxdataF_ext, nr_ue_pbch_vars->dl_ch_estimates_ext, @@ -536,6 +539,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, M = NR_POLAR_PBCH_E; nushift = (Lmax==4)? i_ssb&3 : i_ssb&7; 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,1,&ue->polarList); @@ -605,20 +609,10 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind; - - dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance - dl_indication.dci_ind = NULL; - dl_indication.proc=proc; - dl_indication.module_id=0; - dl_indication.cc_id=proc->CC_id; + uint16_t number_pdus = 1; - rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_MIB; - rx_ind.rx_indication_body[0].mib_pdu.pdu = &decoded_output[0]; //not good as it is pointing to a memory that can change - rx_ind.rx_indication_body[0].mib_pdu.additional_bits = nr_ue_pbch_vars->xtra_byte; - 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++; + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_MIB, gNB_id, ue, NULL, number_pdus); if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication, NULL); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 29841c3186..3ab88dac0a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -48,8 +48,7 @@ extern uint16_t prach_root_sequence_map_0_3[838]; extern uint16_t prach_root_sequence_map_abc[138]; extern uint16_t nr_du[838]; extern int16_t nr_ru[2*839]; -extern const char *prachfmt[9]; -extern const char *prachfmt03[4]; +extern const char *prachfmt[]; // Note: // - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt @@ -72,7 +71,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; int32_t Xu_re, Xu_im; - int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k; + int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot; //int restricted_Type; prach = prach_tmp; @@ -95,7 +94,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ kbar = 1; K = 24; k = 12*n_ra_prb - 6*fp->N_RB_UL; - //prachStartSymbol = prach_config_pdu->prach_start_symbol + prachStartSymbol = prach_pdu->prach_start_symbol; //restricted_Type = 0; compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length, @@ -103,7 +102,10 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, ue->X_u); - prach_start = fp->get_samples_slot_timestamp(slot, fp, 0); + sample_offset_slot = (prachStartSymbol==0?0:fp->ofdm_symbol_size*prachStartSymbol+fp->nb_prefix_samples0+fp->nb_prefix_samples*(prachStartSymbol-1)); + prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot; + + //printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start); // First compute physical root sequence /************************************************************************ @@ -181,14 +183,14 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } // now generate PRACH signal - #ifdef NR_PRACH_DEBUG +#ifdef NR_PRACH_DEBUG if (NCS>0) LOG_I(PHY, "PRACH [UE %d] generate PRACH in slot %d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n", Mod_id, slot, rootSequenceIndex, preamble_index, - prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id], + prachfmt[prach_fmt_id], NCS, N_ZC, preamble_offset, @@ -241,6 +243,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ * *********************************************************/ + if (mu==1) { if (fp->N_RB_UL <= 100) AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL); else if (fp->N_RB_UL < 137) { @@ -321,6 +324,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } } + } + else if (mu==3) { + if (fp->threequarter_fs) + AssertFatal(1==0,"3/4 sampling not supported for numerology %d\n",mu); + + if (prach_sequence_length == 0) + AssertFatal(1==0,"long prach not supported for numerology %d\n",mu); + + if (fp->N_RB_UL == 32) + dftlen=512; + else if (fp->N_RB_UL == 66) + dftlen=1024; + else + AssertFatal(1==0,"N_RB_UL %d not support for numerology %d\n",fp->N_RB_UL,mu); + } + for (offset=0,offset2=0; offsetN_RB_UL <= 100) - AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL); + //actually what we should be checking here is how often the current prach crosses a 0.5ms boundary. I am not quite sure for which paramter set this would be the case, so I will ignore it for now and just check if the prach starts on a 0.5ms boundary + uint8_t use_extended_prach_prefix = 0; + if(fp->numerology_index == 0) { + if (prachStartSymbol == 0 || prachStartSymbol == 7) + use_extended_prach_prefix = 1; + } + else { + if (slot%(fp->slots_per_subframe/2)==0 && prachStartSymbol == 0) + use_extended_prach_prefix = 1; + } + + if (fp->N_RB_UL <= 34) { //32 PRB case 61.44Msps + if (fp->threequarter_fs == 0) { + Ncp<<=1; //to account for 61.44Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_sequence_length == 0) + AssertFatal(1==0,"no long PRACH for this PRACH size %d\n",fp->N_RB_UL); + else { + if (use_extended_prach_prefix) + Ncp+=32; // 16*kappa, kappa=2 for 61.44Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + if (prach_fmt_id != 9) { + memmove(prach2+(512<<1),prach2,(512<<2)); + prach_len = (512*2)+Ncp; + } + else prach_len = (512*1)+Ncp; + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | Prach512 (if ! 0xc0) | + } else if (prach_fmt_id == 5) { // 6x512 + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have |empty | Prach512 | Prach512| empty512 | empty512 | + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | + prach_len = (512*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x512 + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have |empty | Prach512 | Prach512| empty512 | empty512 | empty512 | empty512 + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | empty512 | empty512 + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | + prach_len = (512*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x512 + idft(IDFT_512,prachF,prach2,1); + // here we have |empty | Prach512 | + memmove(prach2+(512<<1),prach2,(512<<2)); + // here we have |empty | Prach512 | Prach512| empty512 | empty512 | empty512 | empty512 + memmove(prach2+(512<<2),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | empty512 | empty512 + memmove(prach2+(512<<3),prach2,(512<<3)); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 + memmove(prach2+(512<<1)*6,prach2,(512<<2)*6); + // here we have |empty | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512| + memmove(prach,prach+(512<<1),(Ncp<<2)); + // here we have |Prefix | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512 | Prach512 | Prach512| Prach512 | Prach512 | Prach512 | Prach512| + prach_len = (512*12)+Ncp; + } + } + } + else + AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL); + + } + else if (fp->N_RB_UL <= 68) {//66 PRB case, 122.88 Msps + if (fp->threequarter_fs == 0) { + Ncp<<=2; //to account for 122.88Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_sequence_length == 0) + AssertFatal(1==0,"no long PRACH for this PRACH size %d\n",fp->N_RB_UL); + else { + if (use_extended_prach_prefix) + Ncp+=64; // 16*kappa, kappa=4 for 122.88Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + if (prach_fmt_id != 9) { + memmove(prach2+(1024<<1),prach2,(1024<<2)); + prach_len = (1024*2)+Ncp; + } + else prach_len = (1024*1)+Ncp; + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | Prach1024 (if ! 0xc0) | + } else if (prach_fmt_id == 5) { // 6x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | + prach_len = (1024*4)+Ncp; + } else if (prach_fmt_id == 6) { // 6x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | empty1024 | empty1024 + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | empty1024 | empty1024 + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | + prach_len = (1024*6)+Ncp; + } else if (prach_fmt_id == 8) { // 12x1024 + idft(IDFT_1024,prachF,prach2,1); + // here we have |empty | Prach1024 | + memmove(prach2+(1024<<1),prach2,(1024<<2)); + // here we have |empty | Prach1024 | Prach1024| empty1024 | empty1024 | empty1024 | empty1024 + memmove(prach2+(1024<<2),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | empty1024 | empty1024 + memmove(prach2+(1024<<3),prach2,(1024<<3)); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 + memmove(prach2+(1024<<1)*6,prach2,(1024<<2)*6); + // here we have |empty | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024| + memmove(prach,prach+(1024<<1),(Ncp<<2)); + // here we have |Prefix | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024 | Prach1024| Prach1024 | Prach1024 | Prach1024 | Prach1024| + prach_len = (1024*12)+Ncp; + } + } + } + else + AssertFatal(1==0,"3/4 sampling not supported for this PRACH size %d\n",fp->N_RB_UL); + } else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s - Ncp<<=1; - // This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s - prach2 = prach+(Ncp<<1); + Ncp<<=1; //to account for 61.44Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s idft(IDFT_49152,prachF,prach2,1); @@ -440,21 +598,20 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (12288*4)+Ncp; } } else { // short PRACH sequence - if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { - Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + if (use_extended_prach_prefix) + Ncp+=32; // 16*kappa, kappa=2 for 61.44Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | - if (prach_fmt_id != 7) { + if (prach_fmt_id != 9) { memmove(prach2+(2048<<1),prach2,(2048<<2)); prach_len = (2048*2)+Ncp; } else prach_len = (2048*1)+Ncp; memmove(prach,prach+(2048<<1),(Ncp<<2)); // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) | - } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048 - Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 5) { // 6x2048 idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | memmove(prach2+(2048<<1),prach2,(2048<<2)); @@ -464,9 +621,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(2048<<1),(Ncp<<2)); // here we have |Prefix | Prach2048 | prach_len = (2048*4)+Ncp; - } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048 - Ncp+=32; - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 6) { // 6x2048 idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | memmove(prach2+(2048<<1),prach2,(2048<<2)); @@ -478,9 +633,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(2048<<1),(Ncp<<2)); // here we have |Prefix | Prach2048 | prach_len = (2048*6)+Ncp; - } else if (prach_fmt_id == 6) { // 12x2048 - Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 8) { // 12x2048 idft(IDFT_2048,prachF,prach2,1); // here we have |empty | Prach2048 | memmove(prach2+(2048<<1),prach2,(2048<<2)); @@ -533,12 +686,13 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (9216*4)+Ncp; } } else { // short sequence - if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + if (use_extended_prach_prefix) + Ncp+=24; // 16*kappa, kappa=1.5 for 46.08Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | - if (prach_fmt_id != 7) { + if (prach_fmt_id != 9) { memmove(prach2+(1536<<1),prach2,(1536<<2)); prach_len = (1536*2)+Ncp; } else prach_len = (1536*1)+Ncp; @@ -546,10 +700,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(1536<<1),(Ncp<<2)); // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) | - } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536 - - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 5) { // 6x1536 idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | memmove(prach2+(1536<<1),prach2,(1536<<2)); @@ -559,9 +710,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(1536<<1),(Ncp<<2)); // here we have |Prefix | Prach1536 | prach_len = (1536*4)+Ncp; - } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536 - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 6) { // 6x1536 idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | memmove(prach2+(1536<<1),prach2,(1536<<2)); @@ -573,9 +722,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(1536<<1),(Ncp<<2)); // here we have |Prefix | Prach1536 | prach_len = (1536*6)+Ncp; - } else if (prach_fmt_id == 6) { // 12x1536 - Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 8) { // 12x1536 idft(IDFT_1536,prachF,prach2,1); // here we have |empty | Prach1536 | memmove(prach2+(1536<<1),prach2,(1536<<2)); @@ -594,8 +741,9 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s - Ncp<<=2; - prach2 = prach+(Ncp<<1); + Ncp<<=2; //to account for 122.88Mbps + // This is after cyclic prefix + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s idft(IDFT_98304,prachF,prach2,1); @@ -630,20 +778,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (24576*4)+Ncp; } } else { // short sequence - if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + if (use_extended_prach_prefix) + Ncp+=64; // 16*kappa, kappa=4 for 122.88Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | - if (prach_fmt_id != 7) { + if (prach_fmt_id != 9) { memmove(prach2+(4096<<1),prach2,(4096<<2)); prach_len = (4096*2)+Ncp; } else prach_len = (4096*1)+Ncp; memmove(prach,prach+(4096<<1),(Ncp<<2)); // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) | - } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096 - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 5) { // 4x4096 idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | memmove(prach2+(4096<<1),prach2,(4096<<2)); @@ -653,9 +800,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(4096<<1),(Ncp<<2)); // here we have |Prefix | Prach4096 | prach_len = (4096*4)+Ncp; - } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096 - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 6) { // 6x4096 idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | memmove(prach2+(4096<<1),prach2,(4096<<2)); @@ -667,9 +812,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(4096<<1),(Ncp<<2)); // here we have |Prefix | Prach4096 | prach_len = (4096*6)+Ncp; - } else if (prach_fmt_id == 6) { // 12x4096 - Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 8) { // 12x4096 idft(IDFT_4096,prachF,prach2,1); // here we have |empty | Prach4096 | memmove(prach2+(4096<<1),prach2,(4096<<2)); @@ -686,8 +829,8 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } } } else { // three quarter sampling @ 92.16 Ms/s - Ncp = (Ncp*3); - prach2 = prach+(Ncp<<1); + Ncp = (Ncp*3); //to account for 92.16 Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples if (prach_sequence_length == 0){ if (prach_fmt_id == 0) { idft(IDFT_73728,prachF,prach2,1); @@ -722,20 +865,19 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ prach_len = (18432*4)+Ncp; } } else { // short sequence - if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + if (use_extended_prach_prefix) + Ncp+=48; // 16*kappa, kappa=3 for 92.16Msps + prach2 = prach+(Ncp<<1); //times 2 for complex samples + if (prach_fmt_id == 4 || prach_fmt_id == 7 || prach_fmt_id == 9) { idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | - if (prach_fmt_id != 7) { + if (prach_fmt_id != 9) { memmove(prach2+(3072<<1),prach2,(3072<<2)); prach_len = (3072*2)+Ncp; } else prach_len = (3072*1)+Ncp; - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | - } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072 - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + memmove(prach,prach+(3072<<1),(Ncp<<2)); + // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | + } else if (prach_fmt_id == 6) { // 6x3072 idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | memmove(prach2+(3072<<1),prach2,(3072<<2)); @@ -747,9 +889,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ memmove(prach,prach+(3072<<1),(Ncp<<2)); // here we have |Prefix | Prach3072 | prach_len = (3072*6)+Ncp; - } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072 - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); + } else if (prach_fmt_id == 5) { // 4x3072 idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | memmove(prach2+(3072<<1),prach2,(3072<<2)); @@ -760,8 +900,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // here we have |Prefix | Prach3072 | prach_len = (3072*4)+Ncp; } else if (prach_fmt_id == 6) { // 12x3072 - Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling - prach2 = prach+(Ncp<<1); idft(IDFT_3072,prachF,prach2,1); // here we have |empty | Prach3072 | memmove(prach2+(3072<<1),prach2,(3072<<2)); 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 845eace8b6..91274b908a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -564,6 +564,18 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, uint32_t llr_offset, uint8_t beamforming_mode); +void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + int32_t **dl_ch_magr, + uint8_t symbol, + uint32_t len, + uint8_t first_symbol_flag, + uint16_t nb_rb, + uint32_t llr_offset, + uint8_t beamforming_mode); /** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, @@ -678,7 +690,7 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, uint8_t *pmi_ext, uint32_t *rb_alloc, uint8_t symbol, - uint8_t subframe, + uint8_t nr_slot_rx, NR_DL_FRAME_PARMS *frame_parms) \brief This function extracts the received resource blocks, both channel estimates and data symbols, for the current allocation and for single antenna eNB transmission. @@ -690,23 +702,10 @@ void dlsch_detection_mrc_TM34(NR_DL_FRAME_PARMS *frame_parms, @param pmi_ext Extracted PMI for chosen RBs @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param subframe Subframe number - @param vrb_type Flag to indicate distributed VRB type + @param nr_slot_rx Slot number @param high_speed_flag @param frame_parms Pointer to frame descriptor */ -/*uint16_t nr_dlsch_extract_rbs_single(int32_t **rxdataF, - int32_t **dl_ch_estimates, - int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - uint16_t pmi, - uint8_t *pmi_ext, - uint32_t *rb_alloc, - uint8_t symbol, - uint8_t subframe, - uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms);*/ - unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, int **dl_ch_estimates, int **rxdataF_ext, @@ -714,12 +713,14 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned short pmi, unsigned char *pmi_ext, unsigned char symbol, - uint8_t pilots, - unsigned short start_rb, - unsigned short nb_pdsch_rb, - unsigned char nr_tti_rx, + uint8_t pilots, + uint8_t config_type, + unsigned short start_rb, + unsigned short nb_pdsch_rb, + unsigned char nr_slot_rx, uint32_t high_speed_flag, - NR_DL_FRAME_PARMS *frame_parms); + NR_DL_FRAME_PARMS *frame_parms, + uint16_t dlDmrsSymbPos); /** \fn dlsch_extract_rbs_dual(int32_t **rxdataF, int32_t **dl_ch_estimates, @@ -740,7 +741,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, @param pmi_ext Extracted PMI for chosen RBs @param rb_alloc RB allocation vector @param symbol Symbol to extract - @param subframe Subframe index + @param nr_slot_rx Slot index @param high_speed_flag @param frame_parms Pointer to frame descriptor */ @@ -754,7 +755,7 @@ unsigned short nr_dlsch_extract_rbs_dual(int **rxdataF, uint8_t pilots, unsigned short start_rb, unsigned short nb_rb_pdsch, - unsigned char nr_tti_rx, + unsigned char nr_slot_rx, uint32_t high_speed_flag, NR_DL_FRAME_PARMS *frame_parms, MIMO_mode_t mimo_mode); @@ -809,6 +810,7 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext, int32_t **dl_ch_estimates_ext, int32_t **dl_ch_mag, int32_t **dl_ch_magb, + int32_t **dl_ch_magr, int32_t **rxdataF_comp, int32_t **rho, NR_DL_FRAME_PARMS *frame_parms, @@ -1002,7 +1004,8 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, NR_DL_FRAME_PARMS *frame_parms, NR_UE_DLSCH_t **dlsch_ue, uint8_t symbol, - uint8_t start_symbol, + uint8_t start_symbol, + uint32_t len, uint16_t nb_rb); /** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several @@ -1017,7 +1020,7 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, @param lte_frame_parms Pointer to frame descriptor @param dlsch Pointer to DLSCH descriptor @param frame Frame number - @param subframe Subframe number + @param nr_slot_rx Slot number @param num_pdcch_symbols Number of PDCCH symbols @param is_crnti indicates if PDSCH belongs to a CRNTI (necessary for parallelizing decoding threads) @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used @@ -1025,13 +1028,15 @@ void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, */ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, + UE_nr_rxtx_proc_t *proc, + int eNB_id, short *dlsch_llr, NR_DL_FRAME_PARMS *frame_parms, NR_UE_DLSCH_t *dlsch, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, + uint16_t nb_symb_sch, + uint8_t nr_slot_rx, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag); @@ -1081,7 +1086,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, - UE_nr_rxtx_proc_t *proc, + UE_nr_rxtx_proc_t *proc, int eNB_id, short *dlsch_llr, NR_DL_FRAME_PARMS *frame_parms, @@ -1089,7 +1094,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, NR_DL_UE_HARQ_t *harq_process, uint32_t frame, uint16_t nb_symb_sch, - uint8_t nr_tti_rx, + uint8_t nr_slot_rx, uint8_t harq_pid, uint8_t is_crnti, uint8_t llr8_flag); @@ -1111,8 +1116,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_NR_UE *phy_vars_ue, uint8_t eNB_id); int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, - uint32_t frame, - uint32_t slot); + UE_nr_rxtx_proc_t *proc); /*! \brief Extract PSS and SSS resource elements @@ -1168,8 +1172,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int nr_pbch_detection(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, - int pbch_initial_symbol, - runmode_t mode); + int pbch_initial_symbol); uint16_t rx_pbch_emul(PHY_VARS_NR_UE *phy_vars_ue, uint8_t eNB_id, @@ -1449,28 +1452,33 @@ void generate_RIV_tables(void); */ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, - runmode_t mode, int n_frames); +/*! + \brief This function gets the carrier frequencies either from FP or command-line-set global variables, depending on the availability of the latter + @param fp Pointer to frame params + @param dl_Carrier Pointer to DL carrier to be set + @param ul_Carrier Pointer to UL carrier to be set +*/ +void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, + uint64_t *dl_Carrier, + uint64_t *ul_Carrier); /*! - \brief Encoding of PUSCH/ACK/RI/ACK from 36-212. - @param a Pointer to ulsch SDU - @param frame_parms Pointer to Frame parameters - @param ulsch Pointer to ulsch descriptor - @param harq_pid HARQ process ID - @param tmode Transmission mode (1-7) - @param control_only_flag Generate PUSCH with control information only - @param Nbundled Parameter for ACK/NAK bundling (36.213 Section 7.3) + \brief This function sets the OAI RF card rx/tx params + @param openair0_cfg Pointer OAI config for a specific card + @param tx_gain_off Tx gain offset + @param rx_gain_off Rx gain offset + @param ul_Carrier UL carrier to be set + @param dl_Carrier DL carrier to be set + @param freq_offset Freq offset to be set */ -uint32_t ulsch_encoding(uint8_t *a, - PHY_VARS_NR_UE *phy_vars_ue, - uint8_t harq_pid, - uint8_t eNB_id, - uint8_t subframe_rx, - uint8_t tmode, - uint8_t control_only_flag, - uint8_t Nbundled); +void nr_rf_card_config(openair0_config_t *openair0_cfg, + double rx_gain_off, + uint64_t ul_Carrier, + uint64_t dl_Carrier, + int freq_offset); + void print_CQI(void *o,UCI_format_t uci_format,uint8_t eNB_id,int N_RB_DL); @@ -1695,9 +1703,8 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset); uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - int frame, - int slot, - fapi_nr_dci_indication_t *dci_ind); + UE_nr_rxtx_proc_t *proc, + fapi_nr_dci_indication_t *dci_ind); /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs @@ -1712,36 +1719,25 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, @param eNB_id eNb index (Nid1) 0,1,2 @param eNB_id_i Interfering eNB index (Nid1) 0,1,2, or 3 in case of MU-MIMO IC receiver @param frame Frame number - @param nr_tti_rx Subframe number + @param nr_slot_rx Slot number @param symbol Symbol on which to act (within sub-frame) @param first_symbol_flag set to 1 on first DLSCH symbol @param rx_type. rx_type=RX_IC_single_stream will enable interference cancellation of a second stream when decoding the first stream. In case of TM1, 2, 5, and this can cancel interference from a neighbouring cell given by eNB_id_i. In case of TM5, eNB_id_i should be set to n_connected_eNB to perform multi-user interference cancellation. In case of TM3, eNB_id_i should be set to eNB_id to perform co-channel interference cancellation; this option should be used together with an interference cancellation step [...]. In case of TM3, if rx_type=RX_IC_dual_stream, both streams will be decoded by applying the IC single stream receiver twice. @param i_mod Modulation order of the interfering stream */ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, 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, + uint8_t nr_slot_rx, unsigned char symbol, unsigned char first_symbol_flag, RX_type_t rx_type, unsigned char i_mod, unsigned char harq_pid); -uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - short *dlsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t *dlsch, - NR_DL_UE_HARQ_t *harq_process, - uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint8_t is_crnti, - uint8_t llr8_flag); - int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe); void *dlsch_thread(void *arg); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index d1dd0f785b..464bcfcfba 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -139,6 +139,10 @@ typedef struct { uint32_t num_of_mod_symbols; // decode phich uint8_t decode_phich; + // Encoder BG + uint8_t BG; + // LDPC lifting size + uint32_t Z; } NR_UL_UE_HARQ_t; typedef struct { @@ -177,9 +181,9 @@ typedef struct { /// Scrambled "b"-sequences (for definition see 36-211 V8.6 2009-03, p.14) uint8_t b_tilde[MAX_NUM_NR_CHANNEL_BITS]; /// Modulated "d"-sequences (for definition see 36-211 V8.6 2009-03, p.14) - uint32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16))); + int32_t d_mod[MAX_NUM_NR_RE] __attribute__ ((aligned(16))); /// Transform-coded "y"-sequences (for definition see 38-211 V15.3.0 2018-09, subsection 6.3.1.4) - uint32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16))); + int32_t y[MAX_NUM_NR_RE] __attribute__ ((aligned(16))); /* /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) uint8_t q[MAX_CQI_PAYLOAD]; @@ -314,6 +318,19 @@ typedef struct { uint8_t codeword; /// HARQ-ACKs NR_UE_HARQ_STATUS_t harq_ack; + /// PTRS Frequency Density + uint8_t PTRSFreqDensity; + /// PTRS Time Density + uint8_t PTRSTimeDensity; + uint8_t PTRSPortIndex ; + uint8_t nEpreRatioOfPDSCHToPTRS; + uint8_t PTRSReOffset; + /// bit mask of PT-RS ofdm symbol indicies + uint16_t ptrs_symbols; + // PTRS symbol index, to be updated every PTRS symbol within a slot. + uint8_t ptrs_symbol_index; + /// PDU BITMAP + uint16_t pduBitmap; } NR_DL_UE_HARQ_t; typedef struct { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c new file mode 100644 index 0000000000..7cf64b28bb --- /dev/null +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c @@ -0,0 +1,90 @@ +/* + * 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 + */ + +/*! \file PHY/NR_UE_TRANSPORT/nr_ue_rf_config.c +* \brief Functional helpers to configure the RF boards at UE side +* \author Guido Casati +* \date 2020 +* \version 0.1 +* \company Fraunhofer IIS +* \email: guido.casati@iis.fraunhofer.de +*/ + +#include "PHY/defs_nr_UE.h" +#include "PHY/phy_extern_nr_ue.h" +#include "nr_transport_proto_ue.h" + +void nr_get_carrier_frequencies(NR_DL_FRAME_PARMS *fp, uint64_t *dl_carrier, uint64_t *ul_carrier){ + + if (downlink_frequency[0][0]) + *dl_carrier = downlink_frequency[0][0]; + else + *dl_carrier = fp->dl_CarrierFreq; + + if (uplink_frequency_offset[0][0]) + *ul_carrier = *dl_carrier + uplink_frequency_offset[0][0]; + else + *ul_carrier = *dl_carrier + fp->ul_CarrierFreq - fp->dl_CarrierFreq; + +} + +void nr_rf_card_config(openair0_config_t *openair0_cfg, + double rx_gain_offset, + uint64_t ul_carrier, + uint64_t dl_carrier, + int freq_offset){ + + uint8_t mod_id = 0; + uint8_t cc_id = 0; + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[mod_id][cc_id]; + int rf_chain = ue->rf_map.chain; + double rx_gain = ue->rx_total_gain_dB; + double tx_gain = ue->tx_total_gain_dB; + + for (int i = rf_chain; i < rf_chain + 4; i++) { + + if (i < openair0_cfg->rx_num_channels) + openair0_cfg->rx_freq[i + rf_chain] = dl_carrier + freq_offset; + else + openair0_cfg->rx_freq[i] = 0.0; + + if (itx_num_channels) + openair0_cfg->tx_freq[i] = ul_carrier + freq_offset; + else + openair0_cfg->tx_freq[i] = 0.0; + + if (tx_gain) + openair0_cfg->tx_gain[i] = tx_gain; + if (rx_gain) + openair0_cfg->rx_gain[i] = rx_gain - rx_gain_offset; + + openair0_cfg->autocal[i] = 1; + + LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n", + i, + rf_chain, + openair0_cfg->tx_gain[i], + openair0_cfg->rx_gain[i], + openair0_cfg->tx_freq[i], + openair0_cfg->rx_freq[i]); + + } +} \ No newline at end of file diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index ee10c96c20..d9bea8a3ac 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -227,12 +227,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, NR_UL_UE_HARQ_t *harq_process; uint16_t nb_rb ; uint32_t A, F; - static uint32_t Z = 0; - uint32_t *pz = &Z; + uint32_t *pz; uint8_t mod_order; uint16_t Kr,r; uint32_t r_offset; - uint8_t BG; uint32_t E,Kb; uint8_t Ilbrm; uint32_t Tbslbrm; @@ -250,12 +248,11 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, harq_process = ulsch->harq_processes[harq_pid]; nb_rb = harq_process->pusch_pdu.rb_size; A = harq_process->pusch_pdu.pusch_data.tb_size*8; - pz = &Z; + pz = &harq_process->Z; mod_order = nr_get_Qm_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table); R = nr_get_code_rate_ul(harq_process->pusch_pdu.mcs_index, harq_process->pusch_pdu.mcs_table); Kr=0; r_offset=0; - BG = 1; F=0; Ilbrm = 0; Tbslbrm = 950984; //max tbs @@ -327,10 +324,10 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Coderate = (float) R /(float) 2048; if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - BG = 2; + harq_process->BG = 2; } else{ - BG = 1; + harq_process->BG = 1; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN); @@ -341,7 +338,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, &harq_process->K, pz, &harq_process->F, - BG); + harq_process->BG); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT); F = harq_process->F; @@ -389,18 +386,22 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, printf("%d \n", harq_process->d[0][cnt]); } printf("\n");*/ - encoder_implemparams_t impp; - impp.n_segments=harq_process->C; - impp.macro_num=0; - impp.tinput = NULL; - impp.tprep = NULL; - impp.tparity = NULL; - impp.toutput = NULL; + encoder_implemparams_t impp = { + .n_segments=harq_process->C, + .macro_num=0, + .tinput = NULL, + .tprep = NULL, + .tparity = NULL, + .toutput = NULL}; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_IN); - - nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,BG,&impp); - + + for(int j = 0; j < (harq_process->C/8 + 1); j++) + { + impp.macro_num = j; + nrLDPC_encoder(harq_process->c,harq_process->d,*pz,Kb,Kr,harq_process->BG,&impp); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LDPC_ENCODER_OPTIM, VCD_FUNCTION_OUT); //stop_meas(te_stats); @@ -448,7 +449,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RATE_MATCHING_LDPC, VCD_FUNCTION_IN); nr_rate_matching_ldpc(Ilbrm, Tbslbrm, - BG, + harq_process->BG, *pz, harq_process->d[r], harq_process->e+r_offset, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index ea79fd467f..208901f289 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -46,9 +46,11 @@ #include "executables/softmodem-common.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" -//#define DEBUG_SCFDMA +#include "PHY/NR_REFSIG/ul_ref_seq_nr.h" + //#define DEBUG_PUSCH_MAPPING //#define DEBUG_MAC_PDU +//#define DEBUG_DFT_IDFT //extern int32_t uplink_counter; @@ -153,6 +155,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, unsigned int G = nr_get_G(nb_rb, number_of_symbols, nb_dmrs_re_per_rb, number_dmrs_symbols, mod_order, Nl); + + nr_ulsch_encoding(ulsch_ue, frame_parms, harq_pid, G); /////////// @@ -184,8 +188,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, (int16_t *)ulsch_ue->d_mod); - // pusch_transform_precoding(ulsch_ue, frame_parms, harq_pid); - + /////////// //////////////////////////////////////////////////////////////////////// @@ -243,26 +246,72 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, l_prime[0] = 0; // single symbol ap 0 -#ifdef NR_SC_FDMA - uint32_t nb_re_pusch, nb_re_dmrs_per_rb; - uint32_t y_offset = 0; + uint16_t index; + uint8_t u = 0, v = 0; + int16_t *dmrs_seq = NULL; - for (l = start_symbol; l < start_symbol + number_of_symbols; l++) { + if (pusch_pdu->transform_precoding == transform_precoder_enabled) { - if((ul_dmrs_symb_pos >> l) & 0x01) - nb_re_dmrs_per_rb = nb_dmrs_re_per_rb; - else - nb_re_dmrs_per_rb = 0; + uint32_t nb_re_pusch=nb_rb * NR_NB_SC_PER_RB; + uint32_t y_offset = 0; + uint16_t num_dmrs_res_per_symbol = nb_rb*(NR_NB_SC_PER_RB/2); - nb_re_pusch = nb_rb * (NR_NB_SC_PER_RB - nb_re_dmrs_per_rb); + // Calculate index to dmrs seq array based on number of DMRS Subcarriers on this symbol + index = get_index_for_dmrs_lowpapr_seq(num_dmrs_res_per_symbol); + u = pusch_pdu->dfts_ofdm.low_papr_group_number; + v = pusch_pdu->dfts_ofdm.low_papr_sequence_number; + dmrs_seq = dmrs_lowpaprtype1_ul_ref_sig[u][v][index]; - nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch); + AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); + + LOG_D(PHY,"Transform Precoding params. u: %d, v: %d, index for dmrsseq: %d\n", u, v, index); + + for (l = start_symbol; l < start_symbol + number_of_symbols; l++) { + + if((ul_dmrs_symb_pos >> l) & 0x01) + /* In the symbol with DMRS no data would be transmitted CDM groups is 2*/ + continue; + + nr_dft(&ulsch_ue->y[y_offset], &((int32_t*)tx_layers[0])[y_offset], nb_re_pusch); + + y_offset = y_offset + nb_re_pusch; + + LOG_D(PHY,"Transform precoding being done on data- symbol: %d, nb_re_pusch: %d, y_offset: %d\n", l, nb_re_pusch, y_offset); + + #ifdef DEBUG_PUSCH_MAPPING + printf("NR_ULSCH_UE: y_offset %d\t nb_re_pusch %d \t Symbol %d \t nb_rb %d \n", + y_offset, nb_re_pusch, l, nb_rb); + #endif + } + + #ifdef DEBUG_DFT_IDFT + int32_t debug_symbols[MAX_NUM_NR_RE] __attribute__ ((aligned(16))); + int offset = 0; + printf("NR_ULSCH_UE: available_bits: %d, mod_order: %d", available_bits,mod_order); + + for (int ll = 0; ll < (available_bits/mod_order); ll++) { + debug_symbols[ll] = ulsch_ue->y[ll]; + } + + printf("NR_ULSCH_UE: numSym: %d, num_dmrs_sym: %d", number_of_symbols,number_dmrs_symbols); + for (int ll = 0; ll < (number_of_symbols-number_dmrs_symbols); ll++) { + + nr_idft(&debug_symbols[offset], nb_re_pusch); + + offset = offset + nb_re_pusch; + + } + LOG_M("preDFT_all_symbols.m","UE_preDFT", tx_layers[0],number_of_symbols*nb_re_pusch,1,1); + LOG_M("postDFT_all_symbols.m","UE_postDFT", ulsch_ue->y,number_of_symbols*nb_re_pusch,1,1); + LOG_M("DEBUG_IDFT_SYMBOLS.m","UE_Debug_IDFT", debug_symbols,number_of_symbols*nb_re_pusch,1,1); + LOG_M("UE_DMRS_SEQ.m","UE_DMRS_SEQ", dmrs_seq,nb_re_pusch,1,1); + #endif - y_offset = y_offset + nb_re_pusch; } -#else - memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t)); -#endif + else + memcpy(ulsch_ue->y, tx_layers[0], (available_bits/mod_order)*sizeof(int32_t)); + /////////// //////////////////////////////////////////////////////////////////////// @@ -279,6 +328,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t k_prime = 0; uint16_t m = 0; + + #ifdef DEBUG_PUSCH_MAPPING + printf("NR_ULSCH_UE: Value of CELL ID %d /t, u %d \n", frame_parms->Nid_cell, u); + #endif + + + // DMRS params for this ap get_Wt(Wt, ap, dmrs_type); get_Wf(Wf, ap, dmrs_type); @@ -295,18 +351,25 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if ((ul_dmrs_symb_pos >> l) & 0x01) { is_dmrs_sym = 1; - if (pusch_pdu->transform_precoding == 1){ // if transform precoding is disabled + + if (pusch_pdu->transform_precoding == transform_precoder_disabled){ + if (dmrs_type == pusch_dmrs_type1) dmrs_idx = start_rb*6; else dmrs_idx = start_rb*4; + + // Perform this on gold sequence, not required when SC FDMA operation is done, + nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + } else { dmrs_idx = 0; - } + } + + + } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { - nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated - - } else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { + AssertFatal(pusch_pdu->transform_precoding == transform_precoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); if(is_ptrs_symbol(l, ulsch_ue->ptrs_symbols)) { is_ptrs_sym = 1; @@ -338,8 +401,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (is_dmrs == 1) { - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + if (pusch_pdu->transform_precoding == transform_precoder_enabled) { + + ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[2*dmrs_idx]) >> 15; + ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*dmrs_seq[(2*dmrs_idx) + 1]) >> 15; + + } else { + + ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*AMP*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + + } #ifdef DEBUG_PUSCH_MAPPING printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t dmrs: %d %d\n", @@ -360,7 +432,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ptrs_idx++; - } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, cdm_grps_no_data, dmrs_type)) { + } else if (!is_dmrs_sym || allowed_xlsch_re_in_dmrs_symbol(k, start_sc, frame_parms->ofdm_symbol_size, cdm_grps_no_data, dmrs_type)) { ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index cf0fc716f9..4ac1c47b02 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -560,7 +560,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change { /* set new value according to rate_change */ frame_parms_ue->ofdm_symbol_size = (frame_parms_ue->ofdm_symbol_size / rate_change); - frame_parms_ue->samples_per_tti = (frame_parms_ue->samples_per_tti / rate_change); frame_parms_ue->samples_per_subframe = (frame_parms_ue->samples_per_subframe / rate_change); free_context_pss_nr(); @@ -588,7 +587,6 @@ void set_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change void restore_frame_context_pss_nr(NR_DL_FRAME_PARMS *frame_parms_ue, int rate_change) { frame_parms_ue->ofdm_symbol_size = frame_parms_ue->ofdm_symbol_size * rate_change; - frame_parms_ue->samples_per_tti = frame_parms_ue->samples_per_tti * rate_change; frame_parms_ue->samples_per_subframe = frame_parms_ue->samples_per_subframe * rate_change; free_context_pss_nr(); @@ -620,8 +618,6 @@ void decimation_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int rate_change, int **r NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); int samples_for_frame = 2*frame_parms->samples_per_frame; - AssertFatal(frame_parms->samples_per_tti > 3839,"Illegal samples_per_tti %d\n",frame_parms->samples_per_tti); - #if TEST_SYNCHRO_TIMING_PSS opp_enabled = 1; diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index dd43fcee5e..3560b23550 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -57,14 +57,14 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, long pucch_GroupHopping, long hoppingId, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t m0, uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch0] start function at slot(nr_tti_tx)=%d\n",nr_tti_tx); + printf("\t [nr_generate_pucch0] start function at slot(nr_slot_tx)=%d\n",nr_slot_tx); #endif /* * Implement TS 38.211 Subclause 6.3.2.3.1 Sequence generation @@ -112,8 +112,8 @@ void nr_generate_pucch0(PHY_VARS_NR_UE *ue, for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", - n_hop,nr_tti_tx); + printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_slot_tx=%d\n", + n_hop,nr_slot_tx); #endif - nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,lprime,nr_slot_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -505,7 +505,7 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t m0, uint8_t nrofSymbols, uint8_t startingSymbolIndex, @@ -514,8 +514,8 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, uint8_t timeDomainOCC, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] start function at slot(nr_tti_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", - nr_tti_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); + printf("\t [nr_generate_pucch1] start function at slot(nr_slot_tx)=%d payload=%d m0=%d nrofSymbols=%d startingSymbolIndex=%d startingPRB=%d startingPRB_intraSlotHopping=%d timeDomainOCC=%d nr_bit=%d\n", + nr_slot_tx,payload,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); #endif /* * Implement TS 38.211 Subclause 6.3.2.4.1 Sequence modulation @@ -603,11 +603,11 @@ void nr_generate_pucch1_old(PHY_VARS_NR_UE *ue, // y_n contains the complex value d multiplied by the sequence r_u_v int16_t y_n_re[12],y_n_im[12]; #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_tti_tx=%d\n", - n_hop,nr_tti_tx); + printf("\t [nr_generate_pucch1] entering function nr_group_sequence_hopping with n_hop=%d, nr_slot_tx=%d\n", + n_hop,nr_slot_tx); #endif - nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value - alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,lnormal,lprime,nr_tti_tx); + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,lnormal,lprime,nr_slot_tx); for (int n=0; n<12; n++) { r_u_v_alpha_delta_re[n] = (int16_t)(((((int32_t)(round(32767*cos(alpha*n))) * table_5_2_2_2_2_Re[u][n])>>15) @@ -806,7 +806,7 @@ inline void nr_pucch2_3_4_scrambling(uint16_t M_bit,uint16_t rnti,uint16_t n_id, int i; uint8_t c; // c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1 - //x2 = (rnti) + ((uint32_t)(1+nr_tti_tx)<<16)*(1+(fp->Nid_cell<<1)); + //x2 = (rnti) + ((uint32_t)(1+nr_slot_tx)<<16)*(1+(fp->Nid_cell<<1)); x2 = ((rnti)<<15)+n_id; #ifdef DEBUG_NR_PUCCH_TX printf("\t\t [nr_pucch2_3_4_scrambling] gold sequence s=%x, M_bit %d\n",s,M_bit); @@ -960,14 +960,14 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, uint16_t startingPRB, uint8_t nr_bit) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch2] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n",nr_tti_tx, payload, nr_bit); + printf("\t [nr_generate_pucch2] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n",nr_slot_tx, payload, nr_bit); #endif // b is the block of bits transmitted on the physical channel after payload coding uint64_t b[16]; // limit to 1024-bit encoded length @@ -1043,7 +1043,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, int m=0; for (int l=0; l>2); ii++) { @@ -1130,7 +1130,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, @@ -1140,7 +1140,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, uint8_t occ_length_format4, uint8_t occ_index_format4) { #ifdef DEBUG_NR_PUCCH_TX - printf("\t [nr_generate_pucch3_4] start function at slot(nr_tti_tx)=%d with payload=%lu and nr_bit=%d\n", nr_tti_tx, payload, nr_bit); + printf("\t [nr_generate_pucch3_4] start function at slot(nr_slot_tx)=%d with payload=%lu and nr_bit=%d\n", nr_slot_tx, payload, nr_bit); #endif // b is the block of bits transmitted on the physical channel after payload coding uint64_t b[16]; @@ -1455,7 +1455,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, for (int l=0; l= (int)floor(nrofSymbols/2))) n_hop = 1; // n_hop = 1 for second hop - nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_tti_tx,&u,&v); // calculating u and v value + nr_group_sequence_hopping(ue->pucch_config_common_nr->pucch_GroupHopping,ue->pucch_config_common_nr->hoppingId,n_hop,nr_slot_tx,&u,&v); // calculating u and v value // Next we proceed to calculate base sequence for DM-RS signal, according to TS 38.211 subclause 6.4.1.33 if (nrofPRB >= 3) { // TS 38.211 subclause 5.2.2.1 (Base sequences of length 36 or larger) applies @@ -1501,7 +1501,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, } uint16_t j=0; - alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_tti_tx); + alpha = nr_cyclic_shift_hopping(ue->pucch_config_common_nr->hoppingId,m0,mcs,l,startingSymbolIndex,nr_slot_tx); for (int rb=0; rbframe_tx; - int slot_number = proc->nr_tti_tx; + int slot_number = proc->nr_slot_tx; uint16_t n_SRS, n_SRS_cs_i; double alpha_i; uint8_t K_TC_p; @@ -278,7 +278,7 @@ int32_t generate_srs_nr(SRS_ResourceSet_t *p_srs_resource_set, n_SRS = l/R; } else { - int8_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe; + int8_t N_slot_frame = frame_parms->slots_per_frame; n_SRS = ((N_slot_frame*frame_number + slot_number - T_offset)/T_SRS)*(N_symb_SRS/R)+(l/R); } @@ -399,7 +399,7 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource, NR_DL_FRAME_PARMS *frame_pa return (-1); } - int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * frame_parms->ttis_per_subframe; + int16_t N_slot_frame = frame_parms->slots_per_frame; if ((N_slot_frame*frame_tx + slot_tx - T_offset)%T_SRS == 0) { return (0); } @@ -445,7 +445,7 @@ int ue_srs_procedure_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB /* SRS resource configurated ? */ if (p_srs_resource != NULL) { if (p_srs_resource_set->resourceType == periodic) { - if (is_srs_period_nr(p_srs_resource, frame_parms, proc->frame_tx, proc->nr_tti_tx) == 0) { + if (is_srs_period_nr(p_srs_resource, frame_parms, proc->frame_tx, proc->nr_slot_tx) == 0) { generate_srs = 1; } } @@ -459,7 +459,7 @@ int ue_srs_procedure_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB if (generate_srs == 1) { int16_t txptr = AMP; uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12; - uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((proc->nr_tti_tx*nsymb)+(nsymb-1)); + uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((proc->nr_slot_tx*nsymb)+(nsymb-1)); if (generate_srs_nr(p_srs_resource_set, frame_parms, &ue->common_vars.txdataF[eNB_id][symbol_offset], txptr, proc) == 0) { return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index e3f1f13a8d..66296910fc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -314,6 +314,7 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, *********************************************************************/ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], uint8_t doPss, uint8_t doSss, @@ -331,7 +332,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, pss_symbol = 0; sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB; - rxdataF = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF; + rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; @@ -386,7 +387,7 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, /******************************************************************* * -* NAME : rx_sss_nr +* NAME : pss_sss_extract_nr * * PARAMETERS : none * @@ -397,11 +398,12 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, *********************************************************************/ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, + UE_nr_rxtx_proc_t *proc, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], uint8_t subframe) { - return do_pss_sss_extract_nr(phy_vars_ue, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); + return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); } /******************************************************************* @@ -417,7 +419,7 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, * *********************************************************************/ -int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) +int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max) { uint8_t i; int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR]; @@ -433,6 +435,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) // pss sss extraction pss_sss_extract_nr(ue, + proc, pss_ext, sss_ext, 0); /* subframe */ @@ -440,8 +443,8 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, int32_t *tot_metric,uint8_t *phase_max) #ifdef DEBUG_PLOT_SSS write_output("rxsig0.m","rxs0",&ue->common_vars.rxdata[0][0],ue->frame_parms.samples_per_subframe,1,1); - write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1); - write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[0]].rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); + write_output("rxdataF0_pss.m","rxF0_pss",&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],frame_parms->ofdm_symbol_size,1,1); + write_output("rxdataF0_sss.m","rxF0_sss",&ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][(SSS_SYMBOL_NB-PSS_SYMBOL_NB)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size,1,1); write_output("pss_ext.m","pss_ext",pss_ext,LENGTH_PSS_NR,1,1); #endif diff --git a/openair1/PHY/TOOLS/dB_routines.c b/openair1/PHY/TOOLS/dB_routines.c index ed5c96a8c3..7a71ac0195 100644 --- a/openair1/PHY/TOOLS/dB_routines.c +++ b/openair1/PHY/TOOLS/dB_routines.c @@ -540,6 +540,289 @@ int16_t dB_table_times10[256] = { 240, 240 }; + + +uint32_t bit_seach_mask[32] = { + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; +uint32_t bit_seach_res[32] = { + 31, 30, 29, 28, + 27, 26, 25, 24, + 23, 22, 21, 20, + 19, 18, 17, 16, + 15, 14, 13, 12, + 11, 10, 9, 8, + 7, 6, 5, 4, + 3, 2, 1, 0 +}; +uint32_t dB_fix_x10_tbl[128] = { +0 , +0 , +1 , +1 , +1 , +2 , +2 , +2 , +3 , +3 , +3 , +4 , +4 , +4 , +5 , +5 , +5 , +5 , +6 , +6 , +6 , +7 , +7 , +7 , +7 , +8 , +8 , +8 , +9 , +9 , +9 , +9 , +10 , +10 , +10 , +10 , +11 , +11 , +11 , +12 , +12 , +12 , +12 , +13 , +13 , +13 , +13 , +14 , +14 , +14 , +14 , +15 , +15 , +15 , +15 , +16 , +16 , +16 , +16 , +16 , +17 , +17 , +17 , +17 , +18 , +18 , +18 , +18 , +19 , +19 , +19 , +19 , +19 , +20 , +20 , +20 , +20 , +20 , +21 , +21 , +21 , +21 , +22 , +22 , +22 , +22 , +22 , +23 , +23 , +23 , +23 , +23 , +24 , +24 , +24 , +24 , +24 , +24 , +25 , +25 , +25 , +25 , +25 , +26 , +26 , +26 , +26 , +26 , +27 , +27 , +27 , +27 , +27 , +27 , +28 , +28 , +28 , +28 , +28 , +29 , +29 , +29 , +29 , +29 , +29 , +30 , +30 , +30 +}; +uint32_t dB_fix_x10_tbl_low[128] = { +0 , +0 , +30 , +48 , +60 , +70 , +78 , +85 , +90 , +95 , +100 , +104 , +108 , +111 , +115 , +118 , +120 , +123 , +126 , +128 , +130 , +132 , +134 , +136 , +138 , +140 , +141 , +143 , +145 , +146 , +148 , +149 , +151 , +152 , +153 , +154 , +156 , +157 , +158 , +159 , +160 , +161 , +162 , +163 , +164 , +165 , +166 , +167 , +168 , +169 , +170 , +171 , +172 , +172 , +173 , +174 , +175 , +176 , +176 , +177 , +178 , +179 , +179 , +180 , +181 , +181 , +182 , +183 , +183 , +184 , +185 , +185 , +186 , +186 , +187 , +188 , +188 , +189 , +189 , +190 , +190 , +191 , +191 , +192 , +192 , +193 , +193 , +194 , +194 , +195 , +195 , +196 , +196 , +197 , +197 , +198 , +198 , +199 , +199 , +200 , +200 , +200 , +201 , +201 , +202 , +202 , +203 , +203 , +203 , +204 , +204 , +205 , +205 , +205 , +206 , +206 , +206 , +207 , +207 , +208 , +208 , +208 , +209 , +209 , +209 , +210 , +210 , +210 +}; + /* int8_t dB_fixed(int x) { @@ -571,6 +854,38 @@ int8_t dB_fixed(int x) { } */ +int16_t dB_fixed_x10(uint32_t x) { + int16_t dB_power = 0; + + //for new algorithm + uint32_t cnt; + uint32_t Exponent; + uint32_t Mantissa; + uint32_t shift_right; + uint32_t tbl_resolution = 7; + uint32_t tbl_addr_mask; + + if (x < 128){ //OAI alogrithm + dB_power = dB_fix_x10_tbl_low[x]; + } + else { //new algorithm + tbl_addr_mask = 0x0000007Fu; // (1 << tbl_resolution) - 1;//i.e. 0x0000007F + Mantissa = 0; + Exponent = 0; + for (cnt = 0; cnt < 32; cnt++) { + if ((bit_seach_mask[cnt] & x) != 0) { + Exponent = bit_seach_res[cnt]; + Mantissa = x & (~bit_seach_mask[cnt]); + break; + } + } + shift_right = Exponent - tbl_resolution; + Mantissa = (Mantissa >> shift_right) & tbl_addr_mask; + dB_power = dB_fix_x10_tbl[Mantissa] + Exponent * 30u; + } + return dB_power; +} + int16_t dB_fixed_times10(uint32_t x) { int16_t dB_power=0; diff --git a/openair1/PHY/TOOLS/dB_routines.h b/openair1/PHY/TOOLS/dB_routines.h index c28184259f..185913cf5b 100644 --- a/openair1/PHY/TOOLS/dB_routines.h +++ b/openair1/PHY/TOOLS/dB_routines.h @@ -30,5 +30,6 @@ #define DB_ROUTINES_H_ int16_t dB_fixed_times10(uint32_t x); +int16_t dB_fixed_x10(uint32_t x); #endif /* DB_ROUTINES_H_ */ diff --git a/openair1/PHY/TOOLS/lte_enb_scope.c b/openair1/PHY/TOOLS/lte_enb_scope.c index b2c6bd909f..19e135ae56 100644 --- a/openair1/PHY/TOOLS/lte_enb_scope.c +++ b/openair1/PHY/TOOLS/lte_enb_scope.c @@ -97,7 +97,7 @@ static void *scope_thread_eNB(void *arg) { } } - sleep(1); + usleep(100*1000); } // printf("%s",stats_buffer); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 8621898d9d..acd22bc78d 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -37,9 +37,12 @@ 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) -{ +void drawsymbol(FL_OBJECT *obj, int id, + FL_POINT *p, int n, int w, int h) { + fl_points( p, n, FL_YELLOW); +} +static void ia_receiver_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "IA Receiver ON"); // PHY_vars_UE_g[0][0]->use_ia_receiver = 1; @@ -51,9 +54,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) } } -static void dl_traffic_on_off( FL_OBJECT *button, long arg) -{ - +static void dl_traffic_on_off( FL_OBJECT *button, long arg) { if (fl_get_button(button)) { fl_set_object_label(button, "DL Traffic ON"); otg_enabled = 1; @@ -65,46 +66,38 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) } } -FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) -{ - +FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) { FL_OBJECT *obj; FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui ); - // Define form fdui->lte_phy_scope_enb = fl_bgn_form( FL_NO_BOX, 800, 800 ); - // This the whole UI box obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" ); fl_set_object_color( obj, FL_BLACK, FL_BLACK ); - // Received signal fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color fl_set_xyplot_ybounds(fdui->rxsig_t,10,70); - // Time-domain channel response fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "SRS Frequency Response (samples, abs)" ); fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color - // Frequency-domain channel response fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color fl_set_xyplot_ybounds( fdui->chest_f,30,70); - // LLR of PUSCH fdui->pusch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pusch_llr, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pusch_llr, FL_BLACK, FL_YELLOW ); fl_set_object_lcolor( fdui->pusch_llr, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pusch_llr,2); - + fl_set_xyplot_symbol(fdui->pusch_llr, 0, drawsymbol); // I/Q PUSCH comp fdui->pusch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 200, "PUSCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pusch_comp, FL_EMBOSSED_BOX ); @@ -112,7 +105,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_lcolor( fdui->pusch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pusch_comp,2); fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pusch_comp, 0, drawsymbol); // I/Q PUCCH comp (format 1) fdui->pucch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 480, 240, 100, "PUCCH1 Energy (SR)" ); fl_set_object_boxtype( fdui->pucch_comp1, FL_EMBOSSED_BOX ); @@ -120,7 +113,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_lcolor( fdui->pucch_comp1, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pucch_comp1,2); // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pucch_comp1, 0, drawsymbol); // I/Q PUCCH comp (fromat 1a/b) fdui->pucch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 600, 240, 100, "PUCCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pucch_comp, FL_EMBOSSED_BOX ); @@ -128,13 +121,12 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_lcolor( fdui->pucch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pucch_comp,2); // fl_set_xyplot_xgrid( fdui->pusch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pucch_comp, 0, drawsymbol); // Throughput on PUSCH fdui->pusch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 480, 500, 100, "PUSCH Throughput [frame]/[kbit/s]" ); fl_set_object_boxtype( fdui->pusch_tput, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pusch_tput, FL_BLACK, FL_WHITE ); fl_set_object_lcolor( fdui->pusch_tput, FL_WHITE ); // Label color - // Generic eNB Button fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" ); fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); @@ -143,18 +135,15 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) fl_set_object_label(fdui->button_0, "DL Traffic OFF"); fl_set_object_color(fdui->button_0, FL_RED, FL_RED); fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 ); - fl_end_form( ); fdui->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) -{ - + int UE_id) { + LOG_D(HW,"scope for UE%d\n", UE_id); int i,i2,arx,atx,ind,k; LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms; int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti; @@ -192,20 +181,18 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, } coded_bits_per_codeword = frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti; - - 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 + 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 bit = malloc(coded_bits_per_codeword*sizeof(float)); rxsig_t = (int16_t**) phy_vars_enb->RU_list[0]->common.rxdata; - //chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id]; - chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates; - chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates; - pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int32_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; - pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; - pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; - pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; + chest_t = (int16_t **) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates; + chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates; + pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr; + pusch_comp = (int32_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; + pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id]; + pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id]; + pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id]; // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -236,7 +223,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, if (chest_t[0] !=NULL) { for (i=0; i<(frame_parms->ofdm_symbol_size); i++) { //i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size; - i2=i; + i2=i; //time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1)); time2[i] = (float)i; chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1])); @@ -278,7 +265,6 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, freq[ind] = (float)ind; Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); - chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im)); ind++; } @@ -333,9 +319,9 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i] < range && pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] > -range && pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1] < range ) { - I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i]; - Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1]; - ind++; + I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i]; + Q[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i+1]; + ind++; } } } @@ -346,75 +332,62 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, // PUSCH I/Q of MF Output if (pucch1ab_comp!=NULL) { for (ind=0; ind<10240; ind++) { - I_pucch[ind] = (float)pucch1ab_comp[2*(ind)]; Q_pucch[ind] = (float)pucch1ab_comp[2*(ind)+1]; A_pucch[ind] = 10*log10(pucch1_comp[ind]); B_pucch[ind] = ind; C_pucch[ind] = (float)pucch1_thres[ind]; } + fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","",""); fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","",""); fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED); fl_set_xyplot_ybounds(form->pucch_comp,-5000,5000); fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000); - fl_set_xyplot_ybounds(form->pucch_comp1,0,80); } - // PUSCH Throughput memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); - tput_time_enb[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; 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,"","",""); - // fl_get_xyplot_ybounds(form->pusch_tput,&ymin,&ymax); // fl_set_xyplot_ybounds(form->pusch_tput,0,ymax); - fl_check_forms(); - free(llr); free(bit); 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 fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 900 ); - // This the whole UI box obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 900, "" ); fl_set_object_color( obj, FL_BLACK, FL_BLACK ); - // Received signal fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" ); fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color fl_set_xyplot_ybounds(fdui->rxsig_t,10,70); - + fl_set_xyplot_symbol(fdui->rxsig_t, 0, drawsymbol); // Time-domain channel response fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" ); fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color - + fl_set_xyplot_symbol(fdui->chest_t, 0, drawsymbol); // Frequency-domain channel response fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" ); fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED ); fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color fl_set_xyplot_ybounds( fdui->chest_f,30,70); - // LLR of PBCH fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX ); @@ -423,23 +396,23 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_xyplot_symbolsize( fdui->pbch_llr,2); fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR); fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920); - + fl_set_xyplot_symbol(fdui->pbch_llr, 0, drawsymbol); // I/Q PBCH comp fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN ); fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pbch_comp,2); + fl_set_xyplot_symbol(fdui->pbch_comp, 0, drawsymbol); // fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100); // fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100); - // LLR of PDCCH fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN ); fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdcch_llr,2); - + fl_set_xyplot_symbol(fdui->pdcch_llr, 0, drawsymbol); // I/Q PDCCH comp fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX ); @@ -447,7 +420,7 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdcch_comp,2); fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pdcch_comp, 0, drawsymbol); // LLR of PDSCH fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" ); fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX ); @@ -455,20 +428,19 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdsch_llr,2); fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR); - + fl_set_xyplot_symbol(fdui->pdsch_llr, 0, drawsymbol); // I/Q PDSCH comp fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500, 240, 200, "PDSCH I/Q of MF Output" ); fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW ); fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color fl_set_xyplot_symbolsize( fdui->pdsch_comp,2); - + fl_set_xyplot_symbol(fdui->pdsch_comp, 0, drawsymbol); // Throughput on PDSCH fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" ); fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX ); fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE ); fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color - // Generic UE Button fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" ); fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER ); @@ -478,10 +450,8 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) fl_set_object_color(fdui->button_0, FL_RED, FL_RED); fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 ); fl_hide_object(fdui->button_0); - fl_end_form( ); fdui->lte_phy_scope_ue->fdui = fdui; - return fdui; } @@ -489,8 +459,7 @@ 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; @@ -521,7 +490,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, unsigned char harq_pid = 0; int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0; - if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) { harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid; @@ -556,34 +524,32 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, coded_bits_per_codeword = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti); } - I = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); - Q = (float*) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); - chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*)); + I = (float *) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); + Q = (float *) calloc(frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*2,sizeof(float)); + chest_t_abs = (float **) malloc(nb_antennas_rx*sizeof(float *)); for (arx=0; arxofdm_symbol_size,sizeof(float)); + 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)); + chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float)); //llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error. - llr = (float*) malloc(coded_bits_per_codeword*sizeof(float)); + 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)); - - rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata; - chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id]; - chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; - pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr; - pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; - pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; - pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; - pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 + llr_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero + bit_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); + rxsig_t = (int16_t **) phy_vars_ue->common_vars.rxdata; + chest_t = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id]; + chest_f = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id]; + pbch_llr = (int8_t *) phy_vars_ue->pbch_vars[eNB_id]->llr; + pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; + pdcch_llr = (int8_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr; + pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0]; + pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0 //pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0 - pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0]; - pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0]; + 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]; // Received signal in time domain of receive antenna 0 if (rxsig_t != NULL) { @@ -652,7 +618,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, freq[ind] = (float)ind; Re = (float)(chest_f[(atx<<1)+arx][(2*k)]); Im = (float)(chest_f[(atx<<1)+arx][(2*k)+1]); - chest_f_abs[ind] = (short)10*log10(1.0+((double)Re*Re + (double)Im*Im)); ind++; } @@ -715,13 +680,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3); - if (frame_parms->N_RB_DL != 100) - { - fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); - } - else - { - LOG_D(PHY,"UE PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); + + if (frame_parms->N_RB_DL != 100) { + fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","",""); + } else { + LOG_D(PHY,"UE PDCCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -731,13 +694,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, I[i] = pdcch_comp[2*i]; Q[i] = pdcch_comp[2*i+1]; } - if (frame_parms->N_RB_DL != 100) - { - fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); - } - else - { - LOG_D(PHY,"UE PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!\n"); + + if (frame_parms->N_RB_DL != 100) { + fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","",""); + } else { + LOG_D(PHY,"UE PDCCH COMP plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -749,13 +710,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); - if (frame_parms->N_RB_DL != 100) - { - fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); - } - else - { - LOG_D(PHY,"UE PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); + + if (frame_parms->N_RB_DL != 100) { + fl_set_xyplot_data(form->pdsch_llr,bit,llr,coded_bits_per_codeword,"","",""); + } else { + LOG_D(PHY,"UE PDSCH LLR plot is bugged in 20 MHz BW, to be fixed !!!\n"); } } @@ -765,7 +724,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, for (k=0; ksymbols_per_tti; k++) { for (i=0; i<12*frame_parms->N_RB_DL/2; i++) { - int j = (2*frame_parms->N_RB_DL*12*k)+4*i; + int j = (2*frame_parms->N_RB_DL*12*k)+4*i; I[ind] = (pdsch_mag[j ]!=0? 1.0/pdsch_mag[j ]: 0.0) * pdsch_comp[j ]*1.0; Q[ind] = (pdsch_mag[j+1]!=0? 1.0/pdsch_mag[j+1]: 0.0) * pdsch_comp[j+1]*1.0; ind++; @@ -778,7 +737,6 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, // PDSCH Throughput memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); memmove( tput_ue[UE_id], &tput_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); - tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame; tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0; @@ -787,11 +745,8 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form, } fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","",""); - fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]); - fl_check_forms(); - free(I); free(Q); free(chest_f_abs); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 78e34036a3..f6cb93ed03 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -25,21 +25,18 @@ #include #include "nr_phy_scope.h" -#include "executables/nr-softmodem-common.h" #include "executables/softmodem-common.h" +#include "executables/nr-softmodem-common.h" #include #define TPUT_WINDOW_LENGTH 100 +#define ScaleZone 4 #define localBuff(NaMe,SiZe) float NaMe[SiZe]; memset(NaMe,0,sizeof(NaMe)); + int otg_enabled; -FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW}; - -float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}}; -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}; +const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW}; +const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED}; typedef struct { int16_t r; @@ -49,10 +46,18 @@ typedef struct { typedef struct OAIgraph { FL_OBJECT *graph; + FL_OBJECT *text; float maxX; float maxY; float minX; float minY; + int x; + int y; + int w; + int h; + int waterFallh; + double *waterFallAvg; + boolean_t initDone; int iteration; void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id); void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id); @@ -94,57 +99,114 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg) { } #endif -static FL_OBJECT *commonGraph( int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { - FL_OBJECT *graph; - graph=fl_add_xyplot(type, x, y, w, h, label); - fl_set_object_lcolor(graph, FL_WHITE ); // Label color - fl_set_object_color(graph, FL_BLACK, pointColor); - fl_set_xyplot_symbol(graph, -1, drawsymbol); - return graph; +#define WATERFALL 10000 + +static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { + if (type==WATERFALL) { + graph->waterFallh=h-15; + graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh); + + for (int i=0; i< graph->waterFallh; i++) + graph->waterFallAvg[i]=0; + + graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label); + graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label); + fl_set_object_lcolor(graph->text,FL_WHITE); + fl_set_object_color(graph->text, FL_BLACK, FL_BLACK); + fl_set_object_lalign(graph->text, FL_ALIGN_CENTER ); + } else { + graph->graph=fl_add_xyplot(type, x, y, w, h, label); + fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color + fl_set_object_color(graph->graph, FL_BLACK, pointColor); + + for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++) + fl_set_xyplot_symbol(graph->graph, i, drawsymbol); + } + + graph->x=x; + graph->y=y; + graph->w=w; + graph->h=h; + graph->maxX=0; + graph->maxY=0; + graph->minX=0; + graph->minY=0; + graph->initDone=false; + graph->iteration=0; } static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id), int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { OAIgraph_t graph; - graph.graph=commonGraph(type, x, y, w, h, label, pointColor); + commonGraph(&graph, type, x, y, w, h, label, pointColor); graph.gNBfunct=funct; graph.nrUEfunct=NULL; - graph.maxX=0; - graph.maxY=0; - graph.minX=0; - graph.minY=0; return graph; } static OAIgraph_t nrUEcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id), int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) { OAIgraph_t graph; - graph.graph=commonGraph(type, x, y, w, h, label, pointColor); + commonGraph(&graph, type, x, y, w, h, label, pointColor); graph.gNBfunct=NULL; graph.nrUEfunct=funct; - graph.maxX=0; - graph.maxY=0; - graph.minX=0; - graph.minY=0; return graph; } static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) { - if ( maxX > graph->maxX || maxY > graph->maxY || minX < graph->minX || minY < graph->minY ) { + if ( maxX > graph->maxX || minX < graph->minX || + abs(maxX-graph->maxX)>abs(graph->maxX)/2 || + abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) { + graph->maxX/=2; + graph->minX/=2; graph->maxX=max(graph->maxX,maxX); graph->minX=min(graph->minX,minX); + fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2); + } + + if ( maxY > graph->maxY || minY < graph->minY || + abs(maxY-graph->maxY)>abs(graph->maxY)/2 || + abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) { + graph->maxY/=2; + graph->minY/=2; graph->maxY=max(graph->maxY,maxY); graph->minY=min(graph->minY,minY); - fl_set_xyplot_ybounds(graph->graph, graph->minY, graph->maxY); - fl_set_xyplot_xbounds(graph->graph, graph->minX, graph->maxX); + fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2); } } -static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, int NoAutoScale) { - if (layer==0) - fl_set_xyplot_data(graph->graph,x,y,len,"","",""); - else - fl_add_xyplot_overlay(graph->graph,layer,x,y,len,rx_antenna_colors[layer]); +static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) { + float *old_x; + float *old_y; + int old_len=-1; + + if (graph->iteration >1) + fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len); + + if (old_len != len) { + LOG_W(HW,"allocating graph of %d scope\n", len); + float values[len]; + float time[len]; + + // make time in case we will use it + for (int i=0; igraph,time,values,len,"","",""); + else + fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]); + + fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len); + AssertFatal(old_len==len,""); + } + + *x=old_x; + *y=old_y; +} + +static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) { + fl_redraw_object(graph->graph); if ( NoAutoScale && graph->iteration%NoAutoScale == 0) { float maxX=0, maxY=0, minX=0, minY=0; @@ -156,46 +218,100 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye minY=min(minY,y[k]); } - setRange(graph,minX,maxX, minY, maxY); + setRange(graph, minX-5, maxX+5, minY-5, maxY+5); } graph->iteration++; } +static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) { + fl_winset(FL_ObjWin(graph->graph)); + const int samplesPerPixel=datasize/graph->w; + int displayPart=graph->waterFallh-ScaleZone; + int row=graph->iteration%displayPart; + double avg=0; + + for (int i=0; i < displayPart; i++) + avg+=graph->waterFallAvg[i]; + + avg/=displayPart; + graph->waterFallAvg[row]=0; + + for (int pix=0; pixw; pix++) { + scopeSample_t *end=values+(pix+1)*samplesPerPixel; + end-=2; + AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize); + double val=0; + + for (scopeSample_t *s=values+(pix)*samplesPerPixel; + s waterFallAvg[row]+=val/graph->w; + int col=0; + + if (val > avg*2 ) + col=1; + + if (val > avg*10 ) + col=2; + + if (val > avg*100 ) + col=3; + + fl_point(pix, graph->iteration%displayPart, water_colors[col]); + } + + if (graph->initDone==false) { + for ( int i=0; i < graph->waterFallh; i++ ) + for ( int j = 0 ; j < graph->w ; j++ ) + fl_point(j, i, FL_BLACK); + + for ( int i=1; iwaterFallh; j++) + fl_point(i*(graph->w/divisions),j, FL_WHITE); + + graph->initDone=true; + } + + fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg)); + graph->iteration++; +} + static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) { - float *values=malloc(len*sizeof(*values)); - float *time=malloc(len*sizeof(*time)); + float *values, *time; + oai_xygraph_getbuff(graph, &time, &values, len, 0); for (int ant=0; antframe_parms; + //use 1st antenna + genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0], + frame_parms->samples_per_frame, frame_parms->slots_per_frame, + "X axis:one frame in time"); +} + +/* replaced by waterfall static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, const int nb_UEs) { // Received signal in time domain of receive antenna 0 if (!phy_vars_ru->common.rxdata) @@ -213,11 +338,12 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy (const scopeSample_t **)phy_vars_ru->common.rxdata, frame_parms->samples_per_frame); } +*/ static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size; - float values[len]; - float time[len]; + float *values, *time; + oai_xygraph_getbuff(graph, &time, &values, len, 0); const int ant=0; // display antenna 0 for each UE for (int ue=0; ueframe_parms; + //use 1st antenna + genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP, + frame_parms->slots_per_frame, + "X axis: Frequency domain, one frame"); +} + +/* static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms; genericLogPowerPerAntena(graph, frame_parms->nb_antennas_rx, (const scopeSample_t **)phy_vars_ru->common.rxdataF, frame_parms->samples_per_slot_wCP); } +*/ static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) { //int Qm = 2; int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti; - float llr[coded_bits_per_codeword]; - float bit[coded_bits_per_codeword]; for (int ue=0; uepusch_vars[ue]->llr; + float *llr, *bit; + oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue); if (pusch_llr) { for (int i=0; iframe_parms; int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot; - float I[sz], Q[sz]; for (int ue=0; uepusch_vars[ue]->rxdataF_comp[0]; + float *I, *Q; + oai_xygraph_getbuff(graph, &I, &Q, sz, ue); if (pusch_comp) { for (int k=0; kgraph[0] = gNBcommonGraph( timeSignal, FL_NORMAL_XYPLOT, 0, curY, 400, 100, - "Received Signal (Time-Domain, dB)", FL_RED ); + fdui->graph[0] = gNBcommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100, + "Received Signal (Time-Domain, one frame)", FL_RED ); // Time-domain channel response fdui->graph[1] = gNBcommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100, "SRS Frequency Response (samples, abs)", FL_RED ); - fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h); + fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h); curY+=h; // Frequency-domain channel response - fdui->graph[2] = gNBcommonGraph( frequencyResponse, FL_NORMAL_XYPLOT, 0, curY, 800, 100, - "Channel Frequency Response (RE, dB)", FL_RED ); + fdui->graph[2] = gNBcommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100, + "Channel Frequency domain (RE, one frame)", FL_RED ); fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h); - curY+=h; + curY+=h+20; // LLR of PUSCH fdui->graph[3] = gNBcommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW ); @@ -376,14 +514,15 @@ void phy_scope_gNB(OAI_phy_scope_t *form, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id) { - static OAI_phy_scope_t *remeberForm=NULL; + static OAI_phy_scope_t *rememberForm=NULL; if (form==NULL) - form=remeberForm; + form=rememberForm; else - remeberForm=form; + rememberForm=form; - if (form==NULL) return; + if (form==NULL) + return; int i=0; @@ -392,7 +531,7 @@ void phy_scope_gNB(OAI_phy_scope_t *form, i++; } - fl_check_forms(); + //fl_check_forms(); } static void *scope_thread_gNB(void *arg) { @@ -406,7 +545,9 @@ static void *scope_thread_gNB(void *arg) { pthread_attr_getstacksize(&atr, &stksize); pthread_attr_setstacksize(&atr,32*1024*1024 ); sleep(3); // no clean interthread barriers - fl_initialize (p->argc, p->argv, NULL, 0, 0); + int fl_argc=1; + char *name="5G-gNB-scope"; + fl_initialize (&fl_argc, &name, NULL, 0, 0); int nb_ue=min(NUMBER_OF_UE_MAX, scope_enb_num_ue); OAI_phy_scope_t *form_gnb = create_phy_scope_gnb(); @@ -425,12 +566,23 @@ void gNBinitScope(scopeParms_t *p) { threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW); } +static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { + // Received signal in time domain of receive antenna 0 + genericWaterFall(graph, + (scopeSample_t *) phy_vars_ue->common_vars.rxdata[0], + phy_vars_ue->frame_parms.samples_per_frame, + phy_vars_ue->frame_parms.slots_per_frame, + "X axis: one frame time"); +} + +/* replaced by waterfall static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Received signal in time domain of receive antenna 0 genericLogPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx, (const scopeSample_t **) phy_vars_ue->common_vars.rxdata, phy_vars_ue->frame_parms.samples_per_frame); } +*/ static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Channel Impulse Response @@ -439,6 +591,17 @@ static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, phy_vars_ue->frame_parms.ofdm_symbol_size>>3); } +static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) { + NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms; + //use 1st antenna + genericWaterFall(graph, + (scopeSample_t *)phy_vars_ue->common_vars.common_vars_rx_data_per_thread[0].rxdataF[0], + frame_parms->samples_per_slot_wCP, + phy_vars_ue->frame_parms.slots_per_frame, + "X axis: one frame frequency" ); +} + +/* static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // Channel Frequency Response (includes 5 complex sample for filter) if (!phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates) @@ -449,12 +612,13 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_gNB; scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates; int ind = 0; - float chest_f_abs[frame_parms->ofdm_symbol_size]; - float freq[frame_parms->ofdm_symbol_size]; + float *freq, *chest_f_abs; + oai_xygraph_getbuff(graph, &freq, &chest_f_abs, frame_parms->ofdm_symbol_size, 0); for (int atx=0; atxofdm_symbol_size; k++) { freq[ind] = (float)ind; chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k])); @@ -471,6 +635,7 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10); } +*/ static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PBCH LLRs @@ -478,11 +643,11 @@ static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ return; int16_t *pbch_llr = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->llr; - float llr_pbch[864], bit_pbch[864]; + float *llr_pbch, *bit_pbch; + oai_xygraph_getbuff(graph, &bit_pbch, &llr_pbch, 864, 0); for (int i=0; i<864; i++) { llr_pbch[i] = (float) pbch_llr[i]; - bit_pbch[i] = (float) i; } oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10); @@ -494,8 +659,10 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i return; scopeSample_t *pbch_comp = (scopeSample_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0]; - localBuff(I,180*3); - localBuff(Q,180*3); + float *I, *Q; + oai_xygraph_getbuff(graph, &I, &Q, 180*3, 0); + memset(I,0,180*3*sizeof(*I)); + memset(Q,0,180*3*sizeof(*Q)); int first_symbol=1; int base=0; @@ -517,7 +684,8 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i base+=nb_re; } - oai_xygraph(graph,I,Q,base,0,10); + AssertFatal(base <= 180*3,""); + oai_xygraph(graph,I,Q,base,0, 10); } static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { @@ -528,8 +696,8 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols int Qm = 2; int coded_bits_per_codeword = num_re*Qm; - localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX); - localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX); + float *llr, *bit; + oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0); int base=0; for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { @@ -537,12 +705,12 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ for (int i=0; iN_RB_DL*num_pdcch_symbols - localBuff(I,nb*RX_NB_TH_MAX); - localBuff(Q,nb*RX_NB_TH_MAX); + float *I, *Q; + oai_xygraph_getbuff(graph, &I, &Q, nb*RX_NB_TH_MAX, 0); int base=0; for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { @@ -567,6 +735,7 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i base+=nb; } + AssertFatal(base <= nb*RX_NB_TH_MAX, ""); oai_xygraph(graph,I,Q,base,0,10); } @@ -578,8 +747,8 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB int num_re = 4500; int Qm = 2; int coded_bits_per_codeword = num_re*Qm; - localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX); - localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX); + float *llr, *bit; + oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0); int base=0; for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { @@ -593,6 +762,7 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB base+=coded_bits_per_codeword; } + AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, ""); //fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); oai_xygraph(graph,bit,llr,base,0,10); } @@ -604,9 +774,11 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer - localBuff(I,sz*RX_NB_TH_MAX); - localBuff(Q,sz*RX_NB_TH_MAX); + float *I, *Q; + oai_xygraph_getbuff(graph, &I, &Q, sz*RX_NB_TH_MAX, 0); int base=0; + memset(I+base, 0, sz*RX_NB_TH_MAX * sizeof(*I)); + memset(Q+base, 0, sz*RX_NB_TH_MAX * sizeof(*Q)); for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[thr][eNB_id]->rxdataF_comp0[0]; @@ -619,11 +791,16 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ base+=sz; } - oai_xygraph(graph,I,Q,base,0,10); + AssertFatal(base <= sz*RX_NB_TH_MAX, ""); + oai_xygraph(graph,I,Q,sz*RX_NB_TH_MAX,0,10); } static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { /* + 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}; + // PDSCH Throughput memmove( tput_time_ue[UE_id], &tput_time_ue[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) ); @@ -652,18 +829,18 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) { fl_set_object_color( obj, FL_BLACK, FL_BLACK ); int curY=0,x,y,w,h; // Received signal - fdui->graph[0] = nrUEcommonGraph(ueTimeResponse, - FL_NORMAL_XYPLOT, 0, curY, 400, 100, "Received Signal (Time-Domain, dB)", FL_RED ); + fdui->graph[0] = nrUEcommonGraph(ueWaterFall, + WATERFALL, 0, curY, 400, 100, "Received Signal (Time-Domain, one frame)", FL_RED ); // Time-domain channel response fdui->graph[1] = nrUEcommonGraph(ueChannelResponse, FL_NORMAL_XYPLOT, 400, curY, 400, 100, "Channel Impulse Response (samples, abs)", FL_RED ); - fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h); + fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h); curY+=h; // Frequency-domain channel response - fdui->graph[2] = nrUEcommonGraph(uePbchFrequencyResp, - FL_IMPULSE_XYPLOT, 0, curY, 800, 100, "Channel Frequency data (RE, dB)", FL_RED ); + fdui->graph[2] = nrUEcommonGraph(ueFreqWaterFall, + WATERFALL, 0, curY, 800, 100, "Channel Frequency (RE, one slot)", FL_RED ); fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h); - curY+=h; + curY+=h+20; // LLR of PBCH fdui->graph[3] = nrUEcommonGraph(uePbchLLR, FL_POINTS_XYPLOT, 0, curY, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)", FL_GREEN ); @@ -733,7 +910,7 @@ void phy_scope_nrUE(OAI_phy_scope_t *form, i++; } - fl_check_forms(); + //fl_check_forms(); } @@ -749,9 +926,12 @@ static void *nrUEscopeThread(void *arg) { OAI_phy_scope_t *form_nrue=create_phy_scope_nrue(0); while (!oai_exit) { + fl_freeze_form(form_nrue->phy_scope); phy_scope_nrUE(form_nrue, ue, 0,0); + fl_unfreeze_form(form_nrue->phy_scope); + fl_redraw_form(form_nrue->phy_scope); usleep(99*1000); } @@ -766,11 +946,11 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) { void nrscope_autoinit(void *dataptr) { AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context"); - + if (IS_SOFTMODEM_GNB_BIT) - gNBinitScope(dataptr); + gNBinitScope(dataptr); else - nrUEinitScope(dataptr); + nrUEinitScope(dataptr); } // Kept to put back the functionality soon #if 0 @@ -799,8 +979,6 @@ static void reset_stats_gNB(FL_OBJECT *button, } } - - static FD_stats_form *create_form_stats_form(int ID) { FL_OBJECT *obj; FD_stats_form *fdui = calloc(( sizeof *fdui ),1); @@ -820,7 +998,3 @@ static FD_stats_form *create_form_stats_form(int ID) { return fdui; } #endif - - - - diff --git a/openair1/PHY/TOOLS/oai_dfts.c b/openair1/PHY/TOOLS/oai_dfts.c index 25244eeff5..e4e85f7ba9 100644 --- a/openair1/PHY/TOOLS/oai_dfts.c +++ b/openair1/PHY/TOOLS/oai_dfts.c @@ -112,7 +112,7 @@ static inline void cmac_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32) { __m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32; - __m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2); + __m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2); cmac_tmp = _mm256_sign_epi16(b,*(__m256i*)reflip); cmac_tmp_re32 = _mm256_madd_epi16(a,cmac_tmp); @@ -129,7 +129,7 @@ static inline void cmacc_256(__m256i a,__m256i b, __m256i *re32, __m256i *im32) { __m256i cmac_tmp,cmac_tmp_re32,cmac_tmp_im32; - __m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,19,18,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2); + __m256i imshuffle = _mm256_set_epi8(29,28,31,30,25,24,27,26,21,20,23,22,17,16,19,18,13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2); cmac_tmp_re32 = _mm256_madd_epi16(a,b); diff --git a/openair1/PHY/TOOLS/signal_energy.c b/openair1/PHY/TOOLS/signal_energy.c index 83bcb7b764..f3dea58374 100644 --- a/openair1/PHY/TOOLS/signal_energy.c +++ b/openair1/PHY/TOOLS/signal_energy.c @@ -29,6 +29,7 @@ #define shift 4 //#define shift_DC 0 +#define SHRT_MIN -32768 #if defined(__x86_64__) || defined(__i386__) #ifdef LOCALIZATION @@ -67,52 +68,39 @@ int32_t subcarrier_energy(int32_t *input,uint32_t length, int32_t *subcarrier_en } #endif +//----------------------------------------------------------------- +// Average Power calculation with DC removing +//----------------------------------------------------------------- int32_t signal_energy(int32_t *input,uint32_t length) { + uint32_t i; + int32_t temp; + __m128i in, in_clp, i16_min, coe1; + __m128 num0, num1, num2, num3, recp1; - int32_t i; - int32_t temp,temp2; - register __m64 mm0,mm1,mm2,mm3; - __m64 *in = (__m64 *)input; + //init + num0 = _mm_setzero_ps(); + num1 = _mm_setzero_ps(); + i16_min = _mm_set1_epi16(SHRT_MIN); + coe1 = _mm_set1_epi16(1); + recp1 = _mm_rcp_ps(_mm_cvtepi32_ps(_mm_set1_epi32(length))); - - mm0 = _mm_setzero_si64();//pxor(mm0,mm0); - mm3 = _mm_setzero_si64();//pxor(mm3,mm3); - - for (i=0; i>1; i++) { - - mm1 = in[i]; - mm2 = mm1; - mm1 = _m_pmaddwd(mm1,mm1); - mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift - mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes - // mm2 = _m_psrawi(mm2,shift_DC); - mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes + //Acc + for (i = 0; i < (length >> 2); i++) { + in = _mm_loadu_si128((__m128i *)input); + in_clp = _mm_subs_epi16(in, _mm_cmpeq_epi16(in, i16_min));//if in=SHRT_MIN in+1, else in + num0 = _mm_add_ps(num0, _mm_cvtepi32_ps(_mm_madd_epi16(in_clp, in_clp))); + num1 = _mm_add_ps(num1, _mm_cvtepi32_ps(_mm_madd_epi16(in, coe1)));//DC + input += 4; } + //Ave + num2 = _mm_dp_ps(num0, recp1, 0xFF);//AC power + num3 = _mm_dp_ps(num1, recp1, 0xFF);//DC + num3 = _mm_mul_ps(num3, num3); //DC power + //remove DC + temp = _mm_cvtsi128_si32(_mm_cvttps_epi32(_mm_sub_ps(num2, num3))); - mm1 = mm0; - mm0 = _m_psrlqi(mm0,32); - mm0 = _m_paddd(mm0,mm1); - temp = _m_to_int(mm0); - temp/=length; - temp<<=shift; // this is the average of x^2 - - - // now remove the DC component - - - mm2 = _m_psrlqi(mm3,32); - mm2 = _m_paddw(mm2,mm3); - mm2 = _m_pmaddwd(mm2,mm2); - temp2 = _m_to_int(mm2); - temp2/=(length*length); - // temp2<<=(2*shift_DC); - temp -= temp2; - - _mm_empty(); - _m_empty(); - - return((temp>0)?temp:1); + return temp; } int32_t signal_energy_amp_shift(int32_t *input,uint32_t length) @@ -163,61 +151,27 @@ int32_t signal_energy_amp_shift(int32_t *input,uint32_t length) int32_t signal_energy_nodc(int32_t *input,uint32_t length) { - int32_t i; int32_t temp; - register __m64 mm0,mm1;//,mm2,mm3; - __m64 *in = (__m64 *)input; - -#ifdef MAIN - int16_t *printb; -#endif - - mm0 = _mm_setzero_si64();//_pxor(mm0,mm0); - // mm3 = _mm_setzero_si64();//pxor(mm3,mm3); - - for (i=0; i>1; i++) { - - mm1 = in[i]; - mm1 = _m_pmaddwd(mm1,mm1);// SIMD complex multiplication - mm1 = _m_psradi(mm1,shift); - mm0 = _m_paddd(mm0,mm1); - // temp2 = mm0; - // printf("%d %d\n",((int *)&in[i])[0],((int *)&in[i])[1]); - - - // printb = (int16_t *)&mm2; - // printf("mm2 %d : %d %d %d %d\n",i,printb[0],printb[1],printb[2],printb[3]); + __m128i in; + __m128 mm0; +//init + mm0 = _mm_setzero_ps(); +//Acc + for (i=0; i<(length>>2); i++) { + in = _mm_loadu_si128((__m128i *)input); + mm0 = _mm_add_ps(mm0,_mm_cvtepi32_ps(_mm_madd_epi16(in,in))); + input += 4; } + //Ave + temp = (int)((((float*)&mm0)[0] + + ((float*)&mm0)[1] + + ((float*)&mm0)[2] + + ((float*)&mm0)[3])/(float)length); - /* - #ifdef MAIN - printb = (int16_t *)&mm3; - printf("%d %d %d %d\n",printb[0],printb[1],printb[2],printb[3]); - #endif - */ - mm1 = mm0; - - mm0 = _m_psrlqi(mm0,32); - - mm0 = _m_paddd(mm0,mm1); - - temp = _m_to_int(mm0); - - temp/=length; - temp<<=shift; // this is the average of x^2 - -#ifdef MAIN - printf("E x^2 = %d\n",temp); -#endif - _mm_empty(); - _m_empty(); - - - - return((temp>0)?temp:1); + return temp; } #elif defined(__arm__) @@ -364,3 +318,66 @@ main(int argc,char **argv) } #endif +#define SHRT_MIN -32768 +int32_t signal_power(int32_t *input, uint32_t length) +{ + + uint32_t i; + int32_t temp; + + __m128i in, in_clp, i16_min; + __m128 num0, num1; + __m128 recp1; + + //init + num0 = _mm_setzero_ps(); + i16_min = _mm_set1_epi16(SHRT_MIN); + recp1 = _mm_rcp_ps(_mm_cvtepi32_ps(_mm_set1_epi32(length))); + //Acc + for (i = 0; i < (length >> 2); i++) { + in = _mm_loadu_si128((__m128i *)input); + in_clp = _mm_subs_epi16(in, _mm_cmpeq_epi16(in, i16_min));//if in=SHRT_MIN in+1, else in + num0 = _mm_add_ps(num0, _mm_cvtepi32_ps(_mm_madd_epi16(in_clp, in_clp))); + input += 4; + } + //Ave + num1 = _mm_dp_ps(num0, recp1, 0xFF); + temp = _mm_cvtsi128_si32(_mm_cvttps_epi32(num1)); + + return temp; +} + +int32_t interference_power(int32_t *input, uint32_t length) +{ + + uint32_t i; + int32_t temp; + + __m128i in, in_clp, i16_min; + __m128i num0, num1, num2, num3; + __m128 num4, num5, num6; + __m128 recp1; + + //init + i16_min = _mm_set1_epi16(SHRT_MIN); + num5 = _mm_setzero_ps(); + recp1 = _mm_rcp_ps(_mm_cvtepi32_ps(_mm_set1_epi32(length>>2)));// 1/n, n= length/4 + //Acc + for (i = 0; i < (length >> 2); i++) { + in = _mm_loadu_si128((__m128i *)input); + in_clp = _mm_subs_epi16(in, _mm_cmpeq_epi16(in, i16_min)); //if in=SHRT_MIN, in+1, else in + num0 = _mm_cvtepi16_epi32(in_clp); //lower 2 complex [0], [1] + num1 = _mm_cvtepi16_epi32(_mm_shuffle_epi32(in_clp, 0x4E)); //upper 2 complex [2], [3] + num2 = _mm_srai_epi32(_mm_add_epi32(num0, num1), 0x01); //average A=complex( [0] + [2] ) / 2, B=complex( [1] + [3] ) / 2 + num3 = _mm_sub_epi32(num2, _mm_shuffle_epi32(num2, 0x4E)); //complexA-complexB, B-A + num4 = _mm_dp_ps(_mm_cvtepi32_ps(num3), _mm_cvtepi32_ps(num3), 0x3F);//C = num3 lower complex power, C, C, C + num5 = _mm_add_ps(num5, num4); //Acc Cn, Cn, Cn, Cn, + input += 4; + } + //Interference ve + num6 = _mm_mul_ps(num5, recp1); //Cn / n + temp = _mm_cvtsi128_si32(_mm_cvttps_epi32(num6)); + + return temp; +} + diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 9c9b8aa821..12467e1fdc 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -431,6 +431,9 @@ int32_t subcarrier_energy(int32_t *,uint32_t, int32_t* subcarrier_energy, uint16 */ int32_t signal_energy_nodc(int32_t *,uint32_t); +int32_t signal_power(int32_t *,uint32_t); +int32_t interference_power(int32_t *,uint32_t); + /*!\fn double signal_energy_fp(double *s_re[2], double *s_im[2],uint32_t, uint32_t,uint32_t); \brief Computes the signal energy per subcarrier */ @@ -469,6 +472,7 @@ uint8_t dB_fixed64(uint64_t x); int8_t dB_fixed2(uint32_t x,uint32_t y); int16_t dB_fixed_times10(uint32_t x); +int16_t dB_fixed_x10(uint32_t x); int32_t phy_phase_compensation_top(uint32_t pilot_type, uint32_t initial_pilot, diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index 1f8c0b8eee..cc3ec94a95 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -32,7 +32,9 @@ #ifndef __PHY_DEFS_NB_IOT__H__ #define __PHY_DEFS_NB_IOT__H__ +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #include #include diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index b8083b5ecf..b465a51a2a 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -191,9 +191,11 @@ typedef struct { int fmt; int numRA; int prachStartSymbol; + int num_prach_ocas; } RU_PRACH_list_t; #define NUMBER_OF_NR_RU_PRACH_MAX 8 +#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12 typedef struct RU_proc_t_s { /// Pointer to associated RU descriptor @@ -594,8 +596,8 @@ typedef struct RU_t_s { RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX]; /// mutex for prach_list access pthread_mutex_t prach_list_mutex; - /// received frequency-domain signal for PRACH (IF4p5 RRU) - int16_t **prach_rxsigF; + /// received frequency-domain signal for PRACH (IF4p5 RRU) + int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX]; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) int16_t **prach_rxsigF_br[4]; /// sequence number for IF5 @@ -622,6 +624,8 @@ typedef struct RU_t_s { int wakeup_L1_sleep_cnt_max; /// DL IF frequency in Hz uint64_t if_frequency; + /// UL IF frequency offset to DL IF frequency in Hz + int if_freq_offset; } RU_t; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 557b8bfc30..0f1bf75114 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -166,6 +166,8 @@ typedef struct { int32_t **ul_ch_magb; /// measured RX power based on DRS int ulsch_power[2]; + /// measured Interference power based on DRS + int ulsch_interference_power[2]; /// \brief llr values. /// - first index: ? [0..1179743] (hard coded) int16_t *llr; @@ -389,6 +391,8 @@ typedef struct { short n0_subband_power_tot_dB[100]; //! estimated avg noise power per RB (dBm) short n0_subband_power_tot_dBm[100]; + //! etimated avg noise power over all RB (dB) + short n0_subband_power_avg_dB; // eNB measurements (per user) //! estimated received spatial signal power (linear) unsigned int rx_spatial_power[NUMBER_OF_UE_MAX][2][2]; @@ -417,6 +421,8 @@ typedef struct { int subband_cqi_tot_dB[NUMBER_OF_UE_MAX][100]; /// PRACH background noise level int prach_I0; + /// PUCCH background noise level + int n0_pucch_dB; } PHY_MEASUREMENTS_eNB; @@ -665,6 +671,7 @@ typedef struct PHY_VARS_eNB_s { int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240]; int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240]; uint8_t *FS6bufferZone; + int32_t pusch_signal_threshold; } PHY_VARS_eNB; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 3fcc9541fe..2598f773a9 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -94,8 +94,6 @@ typedef struct { uint32_t frame; /// Subframe where current HARQ round was sent uint32_t subframe; - /// Index of current HARQ round for this DLSCH - uint8_t round; /// MIMO mode for this DLSCH MIMO_mode_t mimo_mode; /// Concatenated sequences @@ -110,6 +108,10 @@ typedef struct { uint32_t K; /// Number of "Filler" bits uint32_t F; + /// Encoder BG + uint8_t BG; + /// LDPC lifting size + uint32_t Z; } NR_DL_gNB_HARQ_t; typedef struct { @@ -141,8 +143,8 @@ typedef struct { } NR_gNB_SCH_STATS_t; typedef struct { - /// Pointers to 16 HARQ processes for the DLSCH - NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES]; + /// Pointers to variables related to DLSCH harq process + NR_DL_gNB_HARQ_t harq_process; /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) int32_t *txdataF[NR_MAX_NB_LAYERS]; /// Modulated symbols buffer @@ -472,7 +474,7 @@ typedef struct { /// bit mask of PT-RS ofdm symbol indicies uint16_t ptrs_symbols; // PTRS subcarriers per OFDM symbol - uint16_t ptrs_sc_per_ofdm_symbol; + int32_t ptrs_re_per_slot; /// \brief Estimated phase error based upon PTRS on each symbol . /// - first index: ? [0..7] Number of Antenna /// - second index: ? [0...14] smybol per slot @@ -629,32 +631,33 @@ typedef struct { short n0_subband_power_tot_dB[275]; //! estimated avg noise power per RB (dBm) short n0_subband_power_tot_dBm[275]; + // gNB measurements (per user) //! estimated received spatial signal power (linear) - unsigned int rx_spatial_power[NUMBER_OF_NR_DLSCH_MAX][2][2]; + unsigned int rx_spatial_power[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_TX][NB_ANTENNAS_RX]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_NR_DLSCH_MAX][2][2]; + unsigned short rx_spatial_power_dB[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_TX][NB_ANTENNAS_RX]; //! estimated rssi (dBm) - short rx_rssi_dBm[NUMBER_OF_NR_DLSCH_MAX]; + short rx_rssi_dBm[NUMBER_OF_NR_ULSCH_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) - int rx_correlation[NUMBER_OF_NR_DLSCH_MAX][2]; + int rx_correlation[NUMBER_OF_NR_ULSCH_MAX][2]; //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) - int rx_correlation_dB[NUMBER_OF_NR_DLSCH_MAX][2]; + int rx_correlation_dB[NUMBER_OF_NR_ULSCH_MAX][2]; /// Wideband CQI (= SINR) - int wideband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB]; + int wideband_cqi[NUMBER_OF_NR_ULSCH_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI in dB (= SINR dB) - int wideband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB]; + int wideband_cqi_dB[NUMBER_OF_NR_ULSCH_MAX][MAX_NUM_RU_PER_gNB]; /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX]; + char wideband_cqi_tot[NUMBER_OF_NR_ULSCH_MAX]; /// Subband CQI per RX antenna and RB (= SINR) - int subband_cqi[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][275]; + int subband_cqi[NUMBER_OF_NR_ULSCH_MAX][MAX_NUM_RU_PER_gNB][275]; /// Total Subband CQI and RB (= SINR) - int subband_cqi_tot[NUMBER_OF_NR_DLSCH_MAX][275]; + int subband_cqi_tot[NUMBER_OF_NR_ULSCH_MAX][275]; /// Subband CQI in dB and RB (= SINR dB) - int subband_cqi_dB[NUMBER_OF_NR_DLSCH_MAX][MAX_NUM_RU_PER_gNB][275]; + int subband_cqi_dB[NUMBER_OF_NR_ULSCH_MAX][MAX_NUM_RU_PER_gNB][275]; /// Total Subband CQI and RB - int subband_cqi_tot_dB[NUMBER_OF_NR_DLSCH_MAX][275]; + int subband_cqi_tot_dB[NUMBER_OF_NR_ULSCH_MAX][275]; /// PRACH background noise level int prach_I0; } PHY_MEASUREMENTS_gNB; @@ -837,6 +840,7 @@ typedef struct PHY_VARS_gNB_s { notifiedFIFO_t *respDecode; tpool_t *threadPool; int nbDecode; + uint8_t pusch_proc_threads; } PHY_VARS_gNB; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index fff6a82047..390574a66b 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -20,7 +20,7 @@ */ /*! \file PHY/defs_nr_UE.h - \brief Top-level defines and structure definitions for nr ue + \brief Top-level constants and data structures definitions for NR UE \author Guy De Souza, H. WANG, A. Mico Pereperez \date 2018 \version 0.1 @@ -46,9 +46,8 @@ #include "common_lib.h" #include "msc.h" #include "fapi_nr_ue_interface.h" - -//#include #include "assertions.h" + #ifdef MEX #define msg mexPrintf #else @@ -79,9 +78,6 @@ #define openair_free(y,x) free((y)) #define PAGE_SIZE 4096 -//#define RX_NB_TH_MAX 3 -//#define RX_NB_TH 3 - #ifdef NR_UNIT_TEST #define FILE_NAME " " #define LINE_FILE (0) @@ -92,53 +88,19 @@ #define NR_TST_PHY_PRINTF(...) #endif -//#ifdef SHRLIBDEV -//extern int rxrescale; -//#define RX_IQRESCALELEN rxrescale -//#else -//#define RX_IQRESCALELEN 15 -//#endif - -//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards. -//! If no more memory is available, this function will terminate the program with an assertion error. -/*static inline void* malloc16_clear( size_t size ) -{ -#ifdef __AVX2__ - void* ptr = memalign(32, size); -#else - void* ptr = memalign(16, size); -#endif - DevAssert(ptr); - memset( ptr, 0, size ); - return ptr; -}*/ - - - #define PAGE_MASK 0xfffff000 #define virt_to_phys(x) (x) - #define openair_sched_exit() exit(-1) - -//#define max(a,b) ((a)>(b) ? (a) : (b)) -//#define min(a,b) ((a)<(b) ? (a) : (b)) - - #define bzero(s,n) (memset((s),0,(n))) - #define cmax(a,b) ((a>b) ? (a) : (b)) #define cmin(a,b) ((ac) ? (cmax(a,b)) : (c)) - /// suppress compiler warning for unused arguments #define UNUSED(x) (void)x; - #include "impl_defs_top.h" #include "impl_defs_nr.h" - #include "PHY/TOOLS/time_meas.h" #include "PHY/CODING/coding_defs.h" #include "PHY/TOOLS/tools_defs.h" @@ -146,20 +108,14 @@ #include "NR_UE_TRANSPORT/nr_transport_ue.h" #if defined(UPGRADE_RAT_NR) - #include "PHY/NR_REFSIG/ss_pbch_nr.h" - #endif #include "PHY/NR_UE_TRANSPORT/dci_nr.h" -//#include "PHY/LTE_TRANSPORT/defs.h" -//#include "PHY/NR_UE_TRANSPORT/defs_nr.h" #include - #include "targets/ARCH/COMMON/common_lib.h" - -/// Context data structure for eNB subframe processing +/// Context data structure for gNB subframe processing typedef struct { /// Component Carrier index uint8_t CC_id; @@ -177,9 +133,6 @@ typedef enum { #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg typedef struct { - //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) - //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) - //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) // RRC measurements uint32_t rssi; @@ -207,61 +160,59 @@ typedef struct { // UE measurements //! estimated received spatial signal power (linear) - int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + int rx_spatial_power[NUMBER_OF_CONNECTED_gNB_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_gNB_MAX][2][2]; /// estimated received signal power (sum over all TX antennas) - //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX antennas) - //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX/RX antennas) - int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + int rx_power_tot[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) - int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + int rx_power_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) - int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + int wideband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, time average, in dB) - int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + int wideband_cqi_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated rssi (dBm) - short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) - int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][2]; //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) - int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + int rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2]; /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) - int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + int precoded_cqi_dB[NUMBER_OF_CONNECTED_gNB_MAX+1][4]; /// Subband CQI per RX antenna (= SINR) - int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + int subband_cqi[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; /// Total Subband CQI (= SINR) - int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + int subband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; /// Subband CQI in dB (= SINR dB) - int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + int subband_cqi_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; /// Total Subband CQI - int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; /// Wideband PMI for each RX antenna - int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int wideband_pmi_re[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; /// Wideband PMI for each RX antenna - int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int wideband_pmi_im[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; ///Subband PMI for each RX antenna - int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + int subband_pmi_re[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; ///Subband PMI for each RX antenna - int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + int subband_pmi_im[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) - unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; /// Wideband Rank indication - unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char rank[NUMBER_OF_CONNECTED_gNB_MAX]; /// Number of RX Antennas unsigned char nb_antennas_rx; /// DLSCH error counter @@ -338,6 +289,10 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **dl_ch_estimates_ext; + /// \brief Downlink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_ptrs_estimates_ext; /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid /// - second index: ? [0..7] (hard coded) accessed via \c round @@ -375,7 +330,9 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **dl_ch_magb1[8][8]; - /// \brief Cross-correlation of two eNB signals. + /// \brief Magnitude of Downlink Channel, first layer (256QAM level). + int32_t **dl_ch_magr0; + /// \brief Cross-correlation of two gNB signals. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: symbol [0..] int32_t **rho; @@ -414,6 +371,16 @@ typedef struct { uint32_t llr_offset[14]; // llr length per ofdm symbol uint32_t llr_length[14]; + // llr offset per ofdm symbol + uint32_t dl_valid_re[14]; + /// \brief Estimated phase error based upon PTRS on each symbol . + /// - first index: ? [0..7] Number of Antenna + /// - second index: ? [0...14] smybol per slot + int32_t **ptrs_phase_per_slot; + /// \brief Estimated phase error based upon PTRS on each symbol . + /// - first index: ? [0..7] Number of Antenna + /// - second index: ? [0...14] smybol per slot + int32_t **ptrs_re_per_slot; } NR_UE_PDSCH; #define NR_PDCCH_DEFS_NR_UE @@ -633,11 +600,11 @@ typedef struct { /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **dl_ch_estimates_ext; - /// \brief Pointers to channel cross-correlation vectors for multi-eNB detection. + /// \brief Pointers to channel cross-correlation vectors for multi-gNB detection. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx /// - second index: ? [0..168*N_RB_DL[ int32_t **dl_ch_rho_ext; - /// \brief Pointers to channel cross-correlation vectors for multi-eNB detection. + /// \brief Pointers to channel cross-correlation vectors for multi-gNB detection. /// - first index: rx antenna [0..nb_antennas_rx[ /// - second index: ? [0..] int32_t **rho; @@ -734,7 +701,6 @@ typedef struct { int16_t *prachF; int16_t *prach; fapi_nr_ul_config_prach_pdu prach_pdu; - uint8_t prach_Config_enabled; } NR_UE_PRACH; // structure used for multiple SSB detection @@ -771,7 +737,7 @@ typedef struct NR_UL_TIME_ALIGNMENT { int16_t ta_frame; char ta_slot; /// TA command and TAGID received from the gNB - uint8_t ta_command; + uint16_t ta_command; uint8_t tag_id; } NR_UL_TIME_ALIGNMENT_t; @@ -818,8 +784,8 @@ typedef struct { int tx_total_RE[NR_MAX_SLOTS_PER_FRAME]; /// \brief Maximum transmit power int8_t tx_power_max_dBm; - /// \brief Number of eNB seen by UE - uint8_t n_connected_eNB; + /// \brief Number of gNB seen by UE + uint8_t n_connected_gNB; /// \brief indicator that Handover procedure has been initiated uint8_t ho_initiated; /// \brief indicator that Handover procedure has been triggered @@ -835,36 +801,18 @@ typedef struct { fapi_nr_config_request_t nrUE_config; - // the following structures are not part of PHY_vars_UE anymore as it is not thread safe. They are now on the stack of the functions that actually need them - - //nr_downlink_indication_t dl_indication; - //nr_uplink_indication_t ul_indication; - /// UE FAPI DCI request - //nr_dcireq_t dcireq; - - // pointers to the next 2 strcutres are also included in dl_indictation - /// UE FAPI indication for DLSCH reception - //fapi_nr_rx_indication_t rx_ind; - /// UE FAPI indication for DCI reception - //fapi_nr_dci_indication_t dci_ind; - - // point to the current rxTx thread index - uint8_t current_thread_id[NR_MAX_SLOTS_PER_FRAME]; - t_nrPolar_params *polarList; - NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads - NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_PUSCH *pusch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads - NR_UE_ULSCH_t *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words - NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_eNB_MAX]; - NR_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; - // This is for SIC in the UE, to store the reencoded data - LTE_eNB_DLSCH_t *dlsch_eNB[NUMBER_OF_CONNECTED_eNB_MAX]; + NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX+1]; // two RxTx Threads + NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_PUSCH *pusch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_DLSCH_t *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_CODEWORDS]; // two RxTx Threads + NR_UE_ULSCH_t *ulsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_CODEWORDS]; // two code words + NR_UE_DLSCH_t *dlsch_SI[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_DLSCH_t *dlsch_ra[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_DLSCH_t *dlsch_p[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_DLSCH_t *dlsch_MCH[NUMBER_OF_CONNECTED_gNB_MAX]; //Paging parameters uint32_t IMSImod1024; @@ -878,7 +826,7 @@ typedef struct { UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX]; /// cell-specific reference symbols - uint32_t lte_gold_table[7][20][2][14]; + //uint32_t lte_gold_table[7][20][2][14]; #if defined(UPGRADE_RAT_NR) @@ -892,10 +840,10 @@ typedef struct { uint32_t nr_gold_pbch[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; /// PDSCH DMRS - uint32_t nr_gold_pdsch[2][20][2][NR_MAX_PDSCH_DMRS_INIT_LENGTH_DWORD]; + uint32_t ****nr_gold_pdsch[NUMBER_OF_CONNECTED_eNB_MAX]; /// PDCCH DMRS - uint32_t nr_gold_pdcch[7][20][3][52]; + uint32_t ***nr_gold_pdcch[NUMBER_OF_CONNECTED_eNB_MAX]; /// PUSCH DMRS sequence uint32_t ****nr_gold_pusch_dmrs; @@ -905,52 +853,47 @@ typedef struct { uint32_t high_speed_flag; uint32_t perfect_ce; int16_t ch_est_alpha; - int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX]; + int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX]; UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX]; - char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX]; - - unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_gNB_MAX]; + char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_gNB_MAX]; NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX]; int turbo_iterations, turbo_cntl_iterations; /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX]; + /// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded) + uint32_t total_TBS[NUMBER_OF_CONNECTED_gNB_MAX]; /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX]; + /// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded) + uint32_t total_TBS_last[NUMBER_OF_CONNECTED_gNB_MAX]; /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX]; + /// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded) + uint32_t bitrate[NUMBER_OF_CONNECTED_gNB_MAX]; /// \brief ?. - /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) - uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; - int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; - unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; - uint8_t prach_cnt; - uint8_t prach_PreambleIndex; - // uint8_t prach_timer; + /// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded) + uint32_t total_received_bits[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_errors[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_errors_last[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_received[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_received_last[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_fer[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_SI_received[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_SI_errors[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_ra_received[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_ra_errors[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_p_received[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_p_errors[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mch_received[NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; + int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX]; + unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_gNB_MAX]; uint8_t decode_SIB; uint8_t decode_MIB; uint8_t init_sync_frame; @@ -969,9 +912,9 @@ typedef struct { /// Flag to tell if UE is secondary user (cognitive mode) unsigned char is_secondary_ue; - /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. + /// Flag to tell if secondary gNB has channel estimates to create NULL-beams from. unsigned char has_valid_precoder; - /// hold the precoder for NULL beam to the primary eNB + /// hold the precoder for NULL beam to the primary gNB int **ul_precoder_S_UE; /// holds the maximum channel/precoder coefficient char log2_maxp; @@ -997,17 +940,17 @@ typedef struct { double N0; /// PDSCH Varaibles - PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX]; /// PUSCH Varaibles - PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX]; /// PUSCH contention-based access vars PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola /// PUCCH variables - PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX]; //#if defined(UPGRADE_RAT_NR) #if 1 @@ -1018,8 +961,8 @@ typedef struct { PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig; PDSCH_Config_t PDSCH_Config; - PUCCH_ConfigCommon_nr_t pucch_config_common_nr[NUMBER_OF_CONNECTED_eNB_MAX]; - PUCCH_Config_t pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_eNB_MAX]; + PUCCH_ConfigCommon_nr_t pucch_config_common_nr[NUMBER_OF_CONNECTED_gNB_MAX]; + PUCCH_Config_t pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_gNB_MAX]; PUSCH_Config_t pusch_config; SRS_NR srs; @@ -1035,29 +978,29 @@ typedef struct { uint8_t ncs_cell[20][7]; /// UL-POWER-Control - UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_gNB_MAX]; /// TPC - TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX]; - TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX]; + TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_gNB_MAX]; + TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_gNB_MAX]; /// CQI reporting - CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX]; + CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_gNB_MAX]; /// SRS Variables - SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_gNB_MAX]; /// Scheduling Request Config - SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; + SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_gNB_MAX]; //#if defined(UPGRADE_RAT_NR) #if 1 - scheduling_request_config_t scheduling_request_config_nr[NUMBER_OF_CONNECTED_eNB_MAX]; + scheduling_request_config_t scheduling_request_config_nr[NUMBER_OF_CONNECTED_gNB_MAX]; #endif - /// Transmission mode per eNB - uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Transmission mode per gNB + uint8_t transmission_mode[NUMBER_OF_CONNECTED_gNB_MAX]; time_stats_t phy_proc[RX_NB_TH]; time_stats_t phy_proc_tx; @@ -1121,10 +1064,11 @@ typedef struct { SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; #endif + + int dl_stats[5]; } PHY_VARS_NR_UE; - /* this structure is used to pass both UE phy vars and * proc to the function UE_thread_rxn_txnp4 */ @@ -1133,76 +1077,5 @@ typedef struct nr_rxtx_thread_data_s { PHY_VARS_NR_UE *UE; } nr_rxtx_thread_data_t; -/*static inline int wait_on_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - - while (*instance_cnt < 0) { - // most of the time the thread is waiting here - // proc->instance_cnt_rxtx is -1 - pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again - } - - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} - -static inline int wait_on_busy_condition(pthread_mutex_t *mutex,pthread_cond_t *cond,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - - while (*instance_cnt == 0) { - // most of the time the thread will skip this - // waits only if proc->instance_cnt_rxtx is 0 - pthread_cond_wait(cond,mutex); // this unlocks mutex_rxtx while waiting and then locks it again - } - - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} - -static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *name) { - - if (pthread_mutex_lock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error locking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - - *instance_cnt=*instance_cnt-1; - - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("nothing to add"); - return(-1); - } - return(0); -} -*/ - - -/* -#include "PHY/INIT/defs.h" -#include "PHY/LTE_REFSIG/defs.h" -#include "PHY/MODULATION/defs.h" -#include "PHY/LTE_TRANSPORT/proto.h" -#include "PHY/LTE_ESTIMATION/defs.h" -*/ #include "SIMULATION/ETH_TRANSPORT/defs.h" #endif diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index c94d0468b7..18c7dd413b 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -42,11 +42,6 @@ #define nr_subframe_t lte_subframe_t #define nr_slot_t lte_subframe_t -// [hna] This enables SC-FDMA transmission in Uplink. If disabled, then OFDMA is used in UPLINK. -#ifndef NR_SC_FDMA -// #define NR_SC_FDMA -#endif - #define MAX_NUM_SUBCARRIER_SPACING 5 #define NR_MAX_NB_RB 275 @@ -94,7 +89,7 @@ #define NR_MAX_NUM_BWP 4 -#define NR_MAX_PDCCH_AGG_LEVEL 16 +#define NR_MAX_PDCCH_AGG_LEVEL 16 // 3GPP TS 38.211 V15.8 Section 7.3.2 Table 7.3.2.1-1: Supported PDCCH aggregation levels #define NR_MAX_CSET_DURATION 3 #define NR_MAX_NB_RBG 18 @@ -104,6 +99,7 @@ #define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!) #define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH #define NR_MAX_PDSCH_TBS 3824 +#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits. #define MAX_NUM_NR_DLSCH_SEGMENTS 34 #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) @@ -154,6 +150,11 @@ typedef enum { MOD_QAM256 }nr_mod_t; +typedef enum { + RA_2STEP = 0, + RA_4STEP +} nr_ra_type_e; + typedef struct { /// Size of first RBG uint8_t start_size; @@ -209,8 +210,12 @@ typedef struct { uint16_t prach_format; /// Preamble index for PRACH (0-63) uint8_t ra_PreambleIndex; - /// RACH MaskIndex - uint8_t ra_RACH_MaskIndex; + /// Preamble Tx Counter + uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER; + /// Preamble Power Ramping Counter + uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER; + /// 2-step RA power offset + int POWER_OFFSET_2STEP_RA; /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step. int ra_PREAMBLE_RECEIVED_TARGET_POWER; /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex @@ -221,14 +226,16 @@ typedef struct { uint8_t RA_PREAMBLE_BACKOFF; /// uint8_t RA_SCALING_FACTOR_BI; - /// - uint8_t RA_PCMAX; + /// Indicating whether it is 2-step or 4-step RA + nr_ra_type_e RA_TYPE; + /// UE configured maximum output power + int RA_PCMAX; /// Corresponding RA-RNTI for UL-grant uint16_t ra_RNTI; /// Pointer to Msg3 payload for UL-grant uint8_t *Msg3; /// Frame of last completed synch - uint8_t sync_frame; + uint16_t sync_frame; /// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync uint8_t init_msg1; } NR_PRACH_RESOURCES_t; @@ -236,6 +243,7 @@ typedef struct { typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp); +typedef uint32_t (*get_slot_from_timestamp_t)(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp); typedef uint32_t (*get_samples_slot_timestamp_t)(int slot, NR_DL_FRAME_PARMS* fp, uint8_t sl_ahead); @@ -292,14 +300,14 @@ struct NR_DL_FRAME_PARMS { uint32_t samples_per_subframe; /// Number of samples in current slot get_samples_per_slot_t get_samples_per_slot; + /// slot calculation from timestamp + get_slot_from_timestamp_t get_slot_from_timestamp; /// Number of samples before slot get_samples_slot_timestamp_t get_samples_slot_timestamp; /// Number of samples in 0th and center slot of a subframe uint32_t samples_per_slot0; /// Number of samples in other slots of the subframe uint32_t samples_per_slotN0; - /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) - uint16_t symbols_per_tti; /// Number of samples in a radio frame uint32_t samples_per_frame; /// Number of samples in a subframe without CP @@ -308,15 +316,8 @@ struct NR_DL_FRAME_PARMS { uint32_t samples_per_slot_wCP; /// Number of samples in a radio frame without CP uint32_t samples_per_frame_wCP; - /// Number of samples in a tti (same as subrame in LTE, slot in NR) - uint32_t samples_per_tti; /// NR numerology index [0..5] as specified in 38.211 Section 4 (mu). 0=15khZ SCS, 1=30khZ, 2=60kHz, etc uint8_t numerology_index; - /// NR number of ttis per subframe deduced from numerology (cf 38.211): 1, 2, 4, 8(not supported),16(not supported),32(not supported) - uint8_t ttis_per_subframe; - /// NR number of slots per tti . Assumption only 2 Slot per TTI is supported (Slot Config 1 in 38.211) - uint8_t slots_per_tti; -//#endif /// Number of Physical transmit antennas in node uint8_t nb_antennas_tx; /// Number of Receive antennas in node diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 3e09f3f593..ceb75c2554 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -496,8 +496,8 @@ typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference sign uint8_t reportTriggerSize; } csi_MeasConfig_t; typedef enum { - pdsch_dmrs_type1 = 1, - pdsch_dmrs_type2 = 2 + pdsch_dmrs_type1 = 0, + pdsch_dmrs_type2 = 1 } pdsch_dmrs_type_t; typedef enum { pusch_dmrs_type1 = 0, @@ -601,9 +601,11 @@ typedef enum{ ul_rgb_config1 = 1, ul_rgb_config2 = 2 } ul_rgb_Size_t; -typedef enum { - transformPrecoder_enabled = 1, - transformPrecoder_disabled = 2 +/* Aligned values of this enum to other tranform precoder enums + * eg: as defined in fapi_nr_ue_interface.h for transform_precoder_t*/ +typedef enum { + transformPrecoder_enabled = 0, + transformPrecoder_disabled = 1 } transformPrecoder_t; typedef enum { codebookSubset_fullyAndPartialAndNonCoherent = 1, diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h index 6c3d97838d..a8548af8dc 100644 --- a/openair1/PHY/impl_defs_top.h +++ b/openair1/PHY/impl_defs_top.h @@ -219,6 +219,13 @@ ///Third Amplitude for QAM64 (\f$ 2^{15} \times 1/\sqrt{42}\f$) #define QAM64_n3 5056 +///First Amplitude for QAM256 (\f$ 2^{15} \times 8/\sqrt{170}\f$) +#define QAM256_n1 20106 +///Second Amplitude for QAM256 (\f$ 2^{15} \times 4/\sqrt{170}\f$) +#define QAM256_n2 10053 +///Third Amplitude for QAM256 (\f$ 2^{15} \times 2/\sqrt{170}\f$) +#define QAM256_n3 5026 + /// First Amplitude for QAM16 for TM5 (\f$ 2^{15} \times 2/sqrt(20)\f$) #define QAM16_TM5_n1 14654 /// Second Amplitude for QAM16 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{20}\f$) diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h index 2f2a0427f4..700419c61c 100644 --- a/openair1/PHY/phy_extern_nr_ue.h +++ b/openair1/PHY/phy_extern_nr_ue.h @@ -25,6 +25,11 @@ #include "PHY/defs_nr_UE.h" //#include "common/ran_context.h" +#ifdef XFORMS + #include "PHY/TOOLS/nr_phy_scope.h" + extern char do_forms; +#endif + extern char* namepointer_chMag ; extern char* namepointer_log2; extern char fmageren_name2[512]; @@ -32,7 +37,8 @@ extern char fmageren_name2[512]; extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX]; extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX]; -//#include "PHY/LTE_TRANSPORT/transport_extern.h" +extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; +extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; extern const short conjugate[8],conjugate2[8]; extern int number_of_cards; @@ -108,5 +114,8 @@ extern unsigned short Nb_81_110[8][4]; extern uint16_t hundred_times_log10_NPRB[100]; extern uint8_t alpha_lut[8]; extern uint8_t max_turbo_iterations; + +extern double cpuf; + #endif /*__PHY_EXTERN_H__ */ diff --git a/openair1/PHY/thread_NR_UE.h b/openair1/PHY/thread_NR_UE.h index 94271ed55d..901d8faec9 100644 --- a/openair1/PHY/thread_NR_UE.h +++ b/openair1/PHY/thread_NR_UE.h @@ -4,26 +4,18 @@ #include /// Context data structure for RX/TX portion of subframe processing typedef struct { - /// index of the current UE RX/TX proc - int proc_id; + /// index of the current UE RX/TX thread + int thread_id; /// Component Carrier index uint8_t CC_id; /// timestamp transmitted to HW openair0_timestamp timestamp_tx; //#ifdef UE_NR_PHY_DEMO - /// NR TTI index within subframe_tx [0 .. ttis_per_subframe - 1] to act upon for transmission - int nr_tti_tx; - /// NR TTI index within subframe_rx [0 .. ttis_per_subframe - 1] to act upon for reception - int nr_tti_rx; /// NR slot index within frame_tx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_tx; /// NR slot index within frame_rx [0 .. slots_per_frame - 1] to act upon for transmission int nr_slot_rx; //#endif - /// subframe to act upon for transmission - int subframe_tx; - /// subframe to act upon for reception - int subframe_rx; /// frame to act upon for transmission int frame_tx; /// frame to act upon for reception diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 96a073fbb8..3f342802b4 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -992,11 +992,32 @@ void schedule_response(Sched_Rsp_t *Sched_INFO, L1_rxtx_proc_t *proc) { if (NFAPI_MODE!=NFAPI_MONOLITHIC) { if (number_ul_pdu>0) { - //LOG_D(PHY, "UL_CONFIG to send to PNF\n"); - UL_req->sfn_sf = frame << 4 | subframe; - oai_nfapi_ul_config_req(UL_req); - UL_req->ul_config_request_body.number_of_pdus=0; - number_ul_pdu=0; + uint8_t ulsch_pdu_num = 0; + for (i=0; iul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) || + (UL_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) || + (UL_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) || + (UL_req->ul_config_request_body.ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE)){ + ulsch_pdu_num++; + } + } + if (RC.mac[Mod_id]->scheduler_mode == SCHED_MODE_DEFAULT) { + //LOG_D(PHY, "UL_CONFIG to send to PNF\n"); + UL_req->sfn_sf = frame << 4 | subframe; + oai_nfapi_ul_config_req(UL_req); + UL_req->ul_config_request_body.number_of_pdus=0; + number_ul_pdu=0; + }else if (RC.mac[Mod_id]->scheduler_mode == SCHED_MODE_FAIR_RR) { + if(ulsch_pdu_num <= RC.rrc[Mod_id]->configuration.radioresourceconfig[CC_id].ue_multiple_max){ + UL_req->sfn_sf = frame << 4 | subframe; + oai_nfapi_ul_config_req(UL_req); + UL_req->ul_config_request_body.number_of_pdus=0; + number_ul_pdu=0; + }else{ + LOG_E(MAC,"NFAPI: frame %d subframe %d ul_req num %d ul pdu %d\n", + frame,subframe,number_ul_pdu,ulsch_pdu_num); + } + } } } else { for (i=0; iulsch[eNB_id]->harq_processes[harq_pid]->control_only == 1) ? ue->ulsch[eNB_id]->beta_offset_cqi_times8:8; // if deltamcs_enabledm - delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch_x8)>>3))/100.0); + delta_mcs = ((hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_x10((beta_offset_pusch_x8)>>3))/100.0); bw_factor = (hundred_times_log10_NPRB[nb_rb-1]/100.0); #ifdef DEBUG_SEGMENTATION printf("estimated ue tx power %d (num_re %d, sumKr %d, mpr_x100 %d, delta_mcs %f, bw_factor %f)\n", diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index b3e3ab8c4e..38307a7b9e 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -87,9 +87,9 @@ int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t // This is the formula from Section 5.1.1.1 in 36.213 10*log10(deltaIF_PUSCH = (2^(MPR*Ks)-1)*beta_offset_pusch) if (bw_factor == 1) { uint8_t nb_rb = eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb; - return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1]; + return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_x10((beta_offset_pusch)>>3)) + hundred_times_log10_NPRB[nb_rb-1]; } else - return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_times10((beta_offset_pusch)>>3)); + return(hundred_times_delta_TF[MPR_x100/6]+10*dB_fixed_x10((beta_offset_pusch)>>3)); } else { return(0); } @@ -244,8 +244,15 @@ void common_signal_procedures_fembms (PHY_VARS_eNB *eNB,int frame, int subframe) eNB->pbch_configured=0; } - T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), - T_BUFFER(pbch_pdu, 3)); + if (T_ACTIVE(T_ENB_PHY_MIB)) { + /* MIB is stored in reverse in pbch_pdu, reverse it for properly logging */ + uint8_t mib[3]; + mib[0] = pbch_pdu[2]; + mib[1] = pbch_pdu[1]; + mib[2] = pbch_pdu[0]; + T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_BUFFER(mib, 3)); + } generate_pbch_fembms (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, (frame & 15)/4); } //else if ((subframe == 1) && (fp->frame_type == TDD)) { //generate_pss (txdataF, AMP, fp, 2, 2); @@ -313,8 +320,15 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { eNB->pbch_configured=0; } - T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), - T_BUFFER(pbch_pdu, 3)); + if (T_ACTIVE(T_ENB_PHY_MIB)) { + /* MIB is stored in reverse in pbch_pdu, reverse it for properly logging */ + uint8_t mib[3]; + mib[0] = pbch_pdu[2]; + mib[1] = pbch_pdu[1]; + mib[2] = pbch_pdu[0]; + T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_BUFFER(mib, 3)); + } generate_pbch (&eNB->pbch, txdataF, AMP, fp, pbch_pdu, frame & 3); } else if ((subframe == 1) && (fp->frame_type == TDD)) { generate_pss (txdataF, AMP, fp, 2, 2); @@ -743,8 +757,8 @@ void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int // pdu->rx_ue_information.handle = handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; pdu->rx_ue_information.rnti = rnti; - int SNRtimes10 = dB_fixed_times10(stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; - LOG_D(PHY,"stat %d subbandpower %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_dB[0][0], SNRtimes10); + int SNRtimes10 = dB_fixed_x10(stat) - 10 * eNB->measurements.n0_pucch_dB; + LOG_D(PHY,"stat %d n0 %d, SNRtimes10 %d\n", stat, eNB->measurements.n0_subband_power_dB[0][0], SNRtimes10); pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0; @@ -777,6 +791,8 @@ uci_procedures(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci = NULL; LTE_DL_FRAME_PARMS *fp = &(eNB->frame_parms); + calc_pucch_1x_interference(eNB, frame, subframe, 0); + for (int i = 0; i < NUMBER_OF_UCI_VARS_MAX; i++) { uci = &(eNB->uci_vars[i]); @@ -1590,8 +1606,8 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, 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(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; + // estimate UL_CQI for MAC + int SNRtimes10 = dB_fixed_x10(eNB->pusch_vars[UE_id]->ulsch_power[0] + ((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_power[1] : 0 ) ) - dB_fixed_x10(eNB->pusch_vars[UE_id]->ulsch_interference_power[0]+((eNB->frame_parms.nb_antennas_rx>1) ?eNB->pusch_vars[UE_id]->ulsch_interference_power[1] : 0 ) ); if (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi = 0; @@ -1600,8 +1616,8 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, 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,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance, + LOG_D(PHY,"[PUSCH %d] Frame %d Subframe %d Filling RX_indication with SNR %d (%d,%d), timing_advance %d (update %d)\n", + harq_pid,frame,subframe,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,eNB->measurements.n0_subband_power_avg_dB,pdu->rx_indication_rel8.timing_advance, timing_advance_update); eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus++; eNB->UL_INFO.rx_ind.sfn_sf = frame<<4 | subframe; @@ -1905,7 +1921,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in pdu->rx_ue_information.rnti = uci->rnti; // estimate UL_CQI for MAC (from antenna port 0 only) pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - int SNRtimes10 = dB_fixed_times10(uci->stat) - 10 * eNB->measurements.n0_subband_power_dB[0][0]; + int SNRtimes10 = dB_fixed_x10(uci->stat) - 10 * eNB->measurements.n0_pucch_dB; if (SNRtimes10 < -100) LOG_I (PHY, "uci->stat %d \n", uci->stat); @@ -2118,17 +2134,17 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { lte_eNB_I0_measurements (eNB, subframe, 0, eNB->first_run_I0_measurements); int min_I0=1000,max_I0=0; - - if ((frame==0) && (subframe==4)) { + int amin=0,amax=0; + if ((frame==0) && (subframe==3)) { for (int i=0; iframe_parms.N_RB_UL; i++) { if (i==(eNB->frame_parms.N_RB_UL>>1) - 1) i+=2; - if (eNB->measurements.n0_subband_power_tot_dB[i]measurements.n0_subband_power_tot_dB[i]; + if (eNB->measurements.n0_subband_power_tot_dB[i]measurements.n0_subband_power_tot_dB[i]; amin=i;} - if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; + if (eNB->measurements.n0_subband_power_tot_dB[i]>max_I0) {max_I0 = eNB->measurements.n0_subband_power_tot_dB[i]; amax=i;} } - LOG_I (PHY, "max_I0 %d, min_I0 %d\n", max_I0, min_I0); + LOG_I (PHY, "max_I0 %d (rb %d), min_I0 %d (rb %d), avg I0 %d\n", max_I0, amax, min_I0, amin, eNB->measurements.n0_subband_power_avg_dB); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 0 ); diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index eb9a2922c5..b99bb2ee7d 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -80,7 +80,7 @@ void prach_procedures(PHY_VARS_eNB *eNB, ru=eNB->RU_list[i]; for (ru_aa=0,aa=0; ru_aanb_rx; ru_aa++,aa++) { - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa]; int ce_level; if (br_flag==1) diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index e472d64db4..70399f0a23 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -775,7 +775,6 @@ void fep_full(RU_t *ru, if ((fp->frame_type == TDD) && (subframe_select(fp,subframe) != SF_UL)) 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+ru->idx, 1 ); diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index a5d459a7c6..5a98b17cea 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -52,87 +52,114 @@ extern uint8_t nfapi_mode; extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind); -void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot, - nfapi_nr_prach_pdu_t *prach_pdu) { +void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0}; - uint16_t i; - gNB->UL_INFO.rach_ind.number_of_pdus=0; - + uint8_t pdu_index = 0; RU_t *ru; int aa=0; int ru_aa; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); + gNB->UL_INFO.rach_ind.sfn = frame; + gNB->UL_INFO.rach_ind.slot = slot; + gNB->UL_INFO.rach_ind.pdu_list = gNB->prach_pdu_indication_list; + gNB->UL_INFO.rach_ind.number_of_pdus = 0; + ru=gNB->RU_list[0]; + int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST); + + if (prach_id>=0) { + nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu; + uint8_t prachStartSymbol; + uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format); + + /* + uint16_t format,RA_sfn_index; + uint8_t start_symbol,N_t_slot,N_dur,N_RA_slot,config_period; - for (i=0;inum_RU;i++) { - ru=gNB->RU_list[i]; - for (ru_aa=0,aa=0;ru_aanb_rx;ru_aa++,aa++) { - gNB->prach_vars.rxsigF[aa] = gNB->RU_list[i]->prach_rxsigF[ru_aa]; - } - } + get_nr_prach_info_from_index(gNB->gNB_config.prach_config.prach_ConfigurationIndex.value, + frame,slot, + gNB->gNB_config.carrier_config.dl_frequency.value, + gNB->frame_parms.numerology_index, + gNB->frame_parms.frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur, + &RA_sfn_index, + &N_RA_slot, + &config_period); + */ + + for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { + for (ru_aa=0,aa=0;ru_aanb_rx;ru_aa++,aa++) { + gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa]; + } - rx_nr_prach(gNB, - prach_pdu, + prachStartSymbol = prach_pdu->prach_start_symbol+prach_oc*N_dur; + //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. + + rx_nr_prach(gNB, + prach_pdu, + prach_oc, + frame, + slot, + &max_preamble[0], + &max_preamble_energy[0], + &max_preamble_delay[0] + ); + free_nr_prach_entry(gNB,prach_id); + LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", + frame,slot,prach_oc,prachStartSymbol, + max_preamble[0], + max_preamble_energy[0]/10, + max_preamble_delay[0], + gNB->prach_energy_counter); + + if ((gNB->prach_energy_counter == 100) && + (max_preamble_energy[0] > gNB->measurements.prach_I0+100)) { + + LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n", + gNB->Mod_id, frame, slot, - &max_preamble[0], - &max_preamble_energy[0], - &max_preamble_delay[0] - ); - - LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", - frame,slot, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_delay[0], - gNB->prach_energy_counter); - - if ((gNB->prach_energy_counter == 100) && - (max_preamble_energy[0] > gNB->measurements.prach_I0+100)) { - - LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", - gNB->Mod_id, - frame, - slot, - max_preamble[0], - max_preamble_energy[0]/10, - max_preamble_energy[0]%10, - max_preamble_delay[0]); - - T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot), - T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - - - gNB->UL_INFO.rach_ind.number_of_pdus = 1; - gNB->UL_INFO.rach_ind.pdu_list = &gNB->prach_pdu_indication_list[0]; - gNB->UL_INFO.rach_ind.sfn = frame; - gNB->UL_INFO.rach_ind.slot = slot; - - gNB->prach_pdu_indication_list[0].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; - gNB->prach_pdu_indication_list[0].symbol_index = prach_pdu->prach_start_symbol; // FIXME to be changed for multi-ssb (this is only the start symbol of first occasion) - gNB->prach_pdu_indication_list[0].slot_index = slot; - gNB->prach_pdu_indication_list[0].freq_index = prach_pdu->num_ra; - gNB->prach_pdu_indication_list[0].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254; - gNB->prach_pdu_indication_list[0].avg_snr = 0xff; // invalid for now - - - gNB->prach_pdu_indication_list[0].num_preamble = 1; - gNB->prach_pdu_indication_list[0].preamble_list = gNB->preamble_list; - gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_index = max_preamble[0]; - gNB->prach_pdu_indication_list[0].preamble_list[0].timing_advance = max_preamble_delay[0]; - gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_pwr = 0xffffffff; - } - gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); - if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10); - if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++; - - + max_preamble[0], + max_preamble_energy[0]/10, + max_preamble_energy[0]%10, + max_preamble_delay[0], + prachStartSymbol, + prach_pdu->num_ra); + + T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot), + T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); + + + gNB->UL_INFO.rach_ind.number_of_pdus += 1; + + gNB->prach_pdu_indication_list[pdu_index].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; + gNB->prach_pdu_indication_list[pdu_index].symbol_index = prachStartSymbol; + gNB->prach_pdu_indication_list[pdu_index].slot_index = slot; + gNB->prach_pdu_indication_list[pdu_index].freq_index = prach_pdu->num_ra; + gNB->prach_pdu_indication_list[pdu_index].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254; + gNB->prach_pdu_indication_list[pdu_index].avg_snr = 0xff; // invalid for now + + gNB->prach_pdu_indication_list[pdu_index].num_preamble = 1; + gNB->prach_pdu_indication_list[pdu_index].preamble_list = gNB->preamble_list; + gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_index = max_preamble[0]; + gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].timing_advance = max_preamble_delay[0]; + gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; + pdu_index++; + } + gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); + if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10); + if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++; + } //if prach_id>0 + } //for NUMBER_OF_NR_PRACH_OCCASION_MAX VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 9723b2f99e..a78b1f4805 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -89,13 +89,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { if (fp->numerology_index != 0) { if (!(slot%(fp->slots_per_subframe/2))&&(first_symbol==0)) { // case where first symbol in slot has longer prefix - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF], - slot, - 0, - 1, - fp->ofdm_symbol_size); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, @@ -103,13 +96,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { fp->nb_prefix_samples0, CYCLIC_PREFIX); - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], - slot, - 1, - num_symbols-1, - fp->ofdm_symbol_size); - 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, @@ -118,12 +104,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { CYCLIC_PREFIX); } else { // all symbols in slot have shorter prefix - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdataF_BF[aa][slot_offsetF], - slot, - first_symbol, - num_symbols, - fp->ofdm_symbol_size); PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], (int*)&ru->common.txdata[aa][slot_offset], fp->ofdm_symbol_size, @@ -141,12 +121,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { 1, fp->nb_prefix_samples, CYCLIC_PREFIX); - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdata[aa][slot_offset], - slot, - idx_sym, - 1, - fp->ofdm_symbol_size+fp->nb_prefix_samples); slot_offset += fp->nb_prefix_samples+fp->ofdm_symbol_size; } else { @@ -156,12 +130,6 @@ void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { 1, fp->nb_prefix_samples0, CYCLIC_PREFIX); - apply_nr_rotation(fp, - (int16_t*)&ru->common.txdata[aa][slot_offset], - slot, - 0, - 1, - fp->ofdm_symbol_size+fp->nb_prefix_samples0); slot_offset += fp->nb_prefix_samples0+fp->ofdm_symbol_size; } } diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 9d34f496b3..3864b2fcb2 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -252,7 +252,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { 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 * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) { + if (slot_index < TDD_CONFIG_NB_FRAMES * frame_parms->slots_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) { @@ -308,7 +308,7 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms) { * *********************************************************************/ -int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) { +int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_slot) { /* for FFD all slot can be considered as an uplink */ int mu = cfg->ssb_config.scs_common.value,check_slot=0; @@ -318,7 +318,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) if (nr_frame%2 == 0) { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==1) { check_slot++; } } @@ -330,7 +330,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) 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) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) { check_slot++; } } @@ -342,7 +342,7 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) } } else { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); else nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); - + + if (T_ACTIVE(T_GNB_PHY_MIB)) { + unsigned char bch[3]; + bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff; + bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff; + bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff; + T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3)); + } + nr_generate_pbch(&gNB->pbch, &gNB->ssb_pdu, gNB->nr_pbch_interleaver, @@ -193,11 +201,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot); nr_generate_pdsch(gNB,frame, slot); - if ((frame&127) == 0) dump_pdsch_stats(gNB); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } - for (int i=0;icsirs_pdu[i]; if ((csirs->active == 1) && @@ -210,6 +216,11 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, } } + if ((frame&127) == 0) dump_pdsch_stats(gNB); + + //apply the OFDM symbol rotation here + apply_nr_rotation(fp,(int16_t*) &gNB->common_vars.txdataF[0][txdataF_offset],slot,0,fp->Ncp==EXTENDED?12:14,fp->ofdm_symbol_size); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0); } @@ -240,7 +251,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { if (decodeSuccess) { memcpy(ulsch_harq->b+rdata->offset, ulsch_harq->c[r], - rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)); + rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)); } else { if ( rdata->nbSegments != ulsch_harq->processedSegments ) { @@ -258,7 +269,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { if (decodeSuccess) { - LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", + LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for slot %d TBS %d\n", gNB->Mod_id,ulsch_harq->slot,ulsch_harq->TBS); ulsch_harq->status = SCH_IDLE; ulsch_harq->round = 0; @@ -385,7 +396,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, case 245: timing_advance_update /= 32; break; case 273: timing_advance_update /= 32; break; case 66: timing_advance_update /= 12; break; - default: abort(); + case 32: timing_advance_update /= 12; break; + default: AssertFatal(0==1,"No case defined for PRB %d to calculate timing_advance_update\n",gNB->frame_parms.N_RB_DL); } // put timing advance command in 0..63 range @@ -516,7 +528,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) uint8_t symbol; unsigned char aa; - for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) { + for(symbol = 0; symbol < (gNB->frame_parms.Ncp==EXTENDED?12:14); symbol++) { // nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0); for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { @@ -529,6 +541,16 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) 0); } } + + for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { + apply_nr_rotation_ul(&gNB->frame_parms, + gNB->common_vars.rxdataF[aa], + slot_rx, + 0, + gNB->frame_parms.Ncp==EXTENDED?12:14, + gNB->frame_parms.ofdm_symbol_size); + } + } void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { @@ -536,7 +558,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); - fill_ul_rb_mask(gNB, frame_rx, slot_rx); + if (gNB->frame_parms.frame_type == TDD) + fill_ul_rb_mask(gNB, frame_rx, slot_rx); + gNB_I0_measurements(gNB); for (int i=0;islot; // Note: we have to handle the thread IDs for this. To be revisited completely. - thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; + thread_id = scheduled_response->thread_id; NR_UE_DLSCH_t *dlsch0 = NULL; NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0]; @@ -61,11 +64,12 @@ 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; i < dl_config->number_pdus; ++i){ + LOG_D(PHY, "In %s: received 1 DL %s PDU of %d total DL PDUs:\n", __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus); + if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) { fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; @@ -81,6 +85,11 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0]; } + else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){ + dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0]; + dlsch0->rnti_type = _SI_RNTI_; + dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE; + } fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15; uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr; @@ -91,9 +100,10 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti; dlsch0_harq = dlsch0->harq_processes[current_harq_pid]; + LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid); + if (dlsch0_harq){ - dlsch0_harq->status = ACTIVE; dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart; dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize; dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs; @@ -109,11 +119,22 @@ 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 = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame; dlsch0_harq->Nl=1; - dlsch0_harq->mcs_table=0; + dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table; dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type); + if (dlsch0_harq->status != ACTIVE) { + // dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the + // following flag to skip PDSCH procedures in that case. + dlsch0->active = 0; + } dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai; - LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs); - + /* PTRS */ + dlsch0_harq->PTRSFreqDensity = dlsch_config_pdu->PTRSFreqDensity; + dlsch0_harq->PTRSTimeDensity = dlsch_config_pdu->PTRSTimeDensity; + dlsch0_harq->PTRSPortIndex = dlsch_config_pdu->PTRSPortIndex; + dlsch0_harq->nEpreRatioOfPDSCHToPTRS = dlsch_config_pdu->nEpreRatioOfPDSCHToPTRS; + dlsch0_harq->PTRSReOffset = dlsch_config_pdu->PTRSReOffset; + dlsch0_harq->pduBitmap = dlsch_config_pdu->pduBitmap; + LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\tpdsch_to_harq_feedback_time_ind = %d\tslot_for_feedback_ack = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs, dlsch_config_pdu->pdsch_to_harq_feedback_time_ind, dlsch0_harq->harq_ack.slot_for_feedback_ack); } } } @@ -126,6 +147,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ for (i = 0; i < ul_config->number_pdus; ++i){ + LOG_D(PHY, "In %s: processing %s PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_pdu_type[ul_config->ul_config_list[i].pdu_type - 1], ul_config->number_pdus, ul_config); + uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, pucch_resource_id, current_harq_pid, format, gNB_id = 0; /* PRACH */ //NR_PRACH_RESOURCES_t *prach_resources; @@ -154,8 +177,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; - if (scheduled_response->tx_request){ // TBR todo here it should loop through the number of tx pdus - fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body; + if (scheduled_response->tx_request){ + fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[i]; memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length); @@ -221,14 +244,15 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ // prach config pdu prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu)); - PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_Config_enabled = 1; break; default: break; } } - ul_config->number_pdus = 0; + + memset(ul_config, 0, sizeof(fapi_nr_ul_config_request_t)); + } } return 0; diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c index 3c3017d658..f3e5f91285 100644 --- a/openair1/SCHED_NR_UE/harq_nr.c +++ b/openair1/SCHED_NR_UE/harq_nr.c @@ -114,7 +114,7 @@ *********************************************************************/ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted, - NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_tti_rx, uint8_t tx_offset) + NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t slot, uint8_t tx_offset) { if (nr_dci_info_extracted->identifier_dci_formats == DL_DCI) { @@ -124,14 +124,14 @@ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_i dl_harq->harq_ack.vDAI_DL = nr_dci_info_extracted->dai+1; dl_harq->harq_ack.pucch_resource_indicator = nr_dci_info_extracted->pucch_resource_ind; - dl_harq->harq_ack.slot_for_feedback_ack = (nr_tti_rx + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.ttis_per_subframe; + dl_harq->harq_ack.slot_for_feedback_ack = (slot + nr_dci_info_extracted->pdsch_to_harq_feedback_time_ind)%ue->frame_parms.slots_per_subframe; dl_harq->harq_ack.harq_id = nr_dci_info_extracted->harq_process_number; dl_harq->harq_ack.rx_status = downlink_harq_process(dl_harq, dlsch[0]->current_harq_pid, nr_dci_info_extracted->ndi, dlsch[0]->rnti_type); } else if (nr_dci_info_extracted->identifier_dci_formats == UL_DCI) { /* store harq id for which pusch should be transmitted at rx_slot + tx_offset */ - set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (nr_tti_rx + tx_offset)%ue->frame_parms.ttis_per_subframe); + set_tx_harq_id(ulsch, nr_dci_info_extracted->harq_process_number, (slot + tx_offset)%ue->frame_parms.slots_per_subframe); ulsch->harq_processes[nr_dci_info_extracted->harq_process_number]->tx_status = uplink_harq_process(ulsch, nr_dci_info_extracted->harq_process_number, nr_dci_info_extracted->ndi, ulsch->rnti_type); } } @@ -302,7 +302,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u result_harq = NEW_TRANSMISSION_HARQ; - NR_TST_PHY_PRINTF("[HARQ-UL-PUSCH harqId : %d] first new transmission \n", harq_pid); + LOG_D(PHY, "[HARQ-UL-PUSCH harqId : %d] first new transmission \n", harq_pid); } /* 38.321 5.4.2.1 2> if the received grant was not addressed to a Temporary C-RNTI on PDCCH, and the NDI provided in the associated HARQ */ /* information has been toggled compared to the value in the previous transmission of this TB of this HARQ process */ @@ -313,7 +313,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u result_harq = NEW_TRANSMISSION_HARQ; - NR_TST_PHY_PRINTF("[HARQ-UL-PUSCH harqId : %d] new transmission due to toogle of ndi \n", harq_pid); + LOG_D(PHY, "[HARQ-UL-PUSCH harqId : %d] new transmission due to toogle of ndi \n", harq_pid); } /* 38.321 5.4.2.1 2> else (i.e. retransmission): */ else { @@ -322,7 +322,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u result_harq = RETRANSMISSION_HARQ; - NR_TST_PHY_PRINTF("[HARQ-UL-PUSCH harqId : %d] retransmission \n", harq_pid); + LOG_D(PHY, "[HARQ-UL-PUSCH harqId : %d] retransmission \n", harq_pid); } return (result_harq); @@ -476,7 +476,7 @@ harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int result_harq = NEW_TRANSMISSION_HARQ; - NR_TST_PHY_PRINTF("[HARQ-DL-PDSCH harqId : %d] first new reception \n", harq_pid); + LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] first new reception \n", harq_pid); } else if (dl_harq->DCINdi != ndi) { dl_harq->round = 0; @@ -485,15 +485,17 @@ harq_result_t downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int result_harq = NEW_TRANSMISSION_HARQ; - NR_TST_PHY_PRINTF("[HARQ-DL-PDSCH harqId : %d] new reception due to toogle of ndi \n", harq_pid); + LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] new reception due to toogle of ndi \n", harq_pid); } else { dl_harq->round++; + if (dl_harq->harq_ack.ack) dl_harq->status = SCH_IDLE; + result_harq = RETRANSMISSION_HARQ; - NR_TST_PHY_PRINTF("[HARQ-DL-PDSCH harqId : %d] reception of a retransmission \n", harq_pid); + LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] reception of a retransmission \n", harq_pid); } return (result_harq); diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h index ee6e8625b0..c6d47a91ef 100644 --- a/openair1/SCHED_NR_UE/harq_nr.h +++ b/openair1/SCHED_NR_UE/harq_nr.h @@ -73,12 +73,12 @@ @param nr_dci_info_extracted extracted information from dci @param dlsch downlink context @param ulsch uplink context - @param nr_tti_rx rx slot + @param nr_slot_rx rx slot @param tx_offset slot offset for tx @returns none */ void get_dci_info_for_harq(PHY_VARS_NR_UE *ue, NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted, - NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_tti_rx, uint8_t tx_offset); + NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, uint8_t nr_slot_rx, uint8_t tx_offset); /** \brief This function configures uplink HARQ context @param PHY_VARS_NR_UE ue context diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h index 3669239578..fcc2fa5838 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h @@ -61,18 +61,18 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms); /** \brief This function checks nr slot direction : downlink or uplink * @param frame_parms NR DL Frame parameters * @param nr_frame : frame number - * @param nr_tti : slot number + * @param nr_slot : slot number @returns int : downlink or uplink */ -int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti); +int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_slot); /** \brief This function checks nr UE slot direction : downlink or uplink * @param cfg : FAPI Config Request * @param nr_frame : frame number - * @param nr_tti : slot number + * @param nr_slot : slot number @returns int : downlink, uplink or mixed slot type */ -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti); +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot); /** \brief This function frees tdd configuration for nr * @param frame_parms NR DL Frame parameters diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c index 640ffb4ac3..6254f6a2d2 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c @@ -39,7 +39,7 @@ * *********************************************************************/ -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_slot) { /* for FFD all slot can be considered as an uplink */ int mu = cfg->ssb_config.scs_common, check_slot = 0; @@ -49,7 +49,7 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { if (nr_frame%2 == 0) { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { check_slot++; } } @@ -61,7 +61,7 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { check_slot = 0; for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { + if (cfg->tdd_table.max_tdd_periodicity_list[nr_slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { check_slot++; } } @@ -73,7 +73,7 @@ int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { } } else { for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<gNB_index = gNB_id; + dl_ind->module_id = ue->Mod_id; + dl_ind->cc_id = ue->CC_id; + dl_ind->frame = proc->frame_rx; + dl_ind->slot = proc->nr_slot_rx; + dl_ind->thread_id = proc->thread_id; + + if (dci_ind) { + + dl_ind->rx_ind = NULL; //no data, only dci for now + dl_ind->dci_ind = dci_ind; + + } else if (rx_ind) { + + dl_ind->rx_ind = rx_ind; // hang on rx_ind instance + dl_ind->dci_ind = NULL; + + } + +} + +void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, + uint8_t pdu_type, + uint8_t gNB_id, + PHY_VARS_NR_UE *ue, + NR_UE_DLSCH_t *dlsch0, + uint16_t n_pdus){ + + int harq_pid; + NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + + if (n_pdus > 1){ + LOG_E(PHY, "In %s: multiple number of DL PDUs not supported yet...\n", __FUNCTION__); + } + + switch (pdu_type){ + case FAPI_NR_RX_PDU_TYPE_DLSCH: + case FAPI_NR_RX_PDU_TYPE_RAR: + harq_pid = dlsch0->current_harq_pid; + rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b; + rx_ind->rx_indication_body[n_pdus - 1].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS / 8; + break; + case FAPI_NR_RX_PDU_TYPE_MIB: + rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.pdu = ue->pbch_vars[gNB_id]->decoded_output; + rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.additional_bits = ue->pbch_vars[gNB_id]->xtra_byte; + rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_index = frame_parms->ssb_index; + rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.ssb_length = frame_parms->Lmax; + rx_ind->rx_indication_body[n_pdus - 1].mib_pdu.cell_id = frame_parms->Nid_cell; + break; + default: + break; + } + + rx_ind->rx_indication_body[n_pdus -1].pdu_type = pdu_type; + rx_ind->number_pdus = n_pdus; + +} + int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){ int gain_dB = power_dBm - power_max_dBm, amp_x_100 = -1; @@ -134,10 +196,17 @@ UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]); } -uint16_t get_bw_scaling(uint16_t bwp_ul_NB_RB){ +uint8_t get_ra_PreambleIndex(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id){ + + return PHY_vars_UE_g[Mod_id][CC_id]->prach_resources[gNB_id]->ra_PreambleIndex; + +} + + +// scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size +uint16_t get_bw_scaling(uint16_t nb_rb){ uint16_t bw_scaling; - // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size - switch (bwp_ul_NB_RB) { + switch (nb_rb) { case 32: bw_scaling = 4; break; case 66: bw_scaling = 8; break; case 106: bw_scaling = 16; break; @@ -149,41 +218,69 @@ uint16_t get_bw_scaling(uint16_t bwp_ul_NB_RB){ return bw_scaling; } -void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){ +// UL time alignment procedures: +// - If the current tx frame and slot match the TA configuration in ul_time_alignment +// then timing advance is processed and set to be applied in the next UL transmission +// - Application of timing adjustment according to TS 38.213 p4.2 +// todo: +// - handle RAR TA application as per ch 4.2 TS 38.213 +void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ - // 3GPP TS 38.213 p4.2 - // scale by the scs numerology - int factor_mu = 1 << mu; - uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); + if (ue->mac_enabled == 1) { - PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu; + uint8_t gNB_id = 0; + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; - LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %d\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); -} + if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) { -// WIP -// - todo: handle TA application as per ch 4.2 TS 38.213 -void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint16_t ta_command) { + uint8_t numerology = ue->frame_parms.numerology_index; + uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL; + int factor_mu = 1 << numerology; + uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); - int factor_mu = 1 << ue->frame_parms.numerology_index; - uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL; - uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); + LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d -- UE_mode %d\n", __FUNCTION__, frame_tx, slot_tx, ue->UE_mode[gNB_id]); - // Transmission timing adjustment (TS 38.213 p4.2) - ue->timing_advance = bw_scaling / factor_mu; + if (ue->UE_mode[gNB_id] == RA_RESPONSE){ - LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, proc->frame_rx, proc->nr_tti_rx, ta_command, ue->timing_advance); + ue->timing_advance = ul_time_alignment->ta_command * bw_scaling / factor_mu; + + LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %d new value is %u \n", + __FUNCTION__, + ue->Mod_id, + frame_tx, + slot_tx, + ul_time_alignment->ta_command, + ue->timing_advance); + + } else if (ue->UE_mode[gNB_id] == PUSCH){ + + ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu; + + LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n", + __FUNCTION__, + ue->Mod_id, + frame_tx, + slot_tx, + ul_time_alignment->ta_command, + ue->timing_advance); + + } + + ul_time_alignment->ta_frame = -1; + ul_time_alignment->ta_slot = -1; + + } + } } void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - uint8_t thread_id){ - //int32_t ulsch_start=0; - int slot_tx = proc->nr_tti_tx; + uint8_t gNB_id) { + + int slot_tx = proc->nr_slot_tx; int frame_tx = proc->frame_tx; - uint8_t harq_pid = 0; - runmode_t mode = normal_txrx; + + AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); @@ -195,32 +292,30 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, start_meas(&ue->phy_proc_tx); #endif - if (ue->UE_mode[gNB_id] <= PUSCH || get_softmodem_params()->phy_test == 1){ + if (ue->UE_mode[gNB_id] <= PUSCH){ - if (ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE) - nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, thread_id, gNB_id); + for (uint8_t harq_pid = 0; harq_pid < ue->ulsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pusch; harq_pid++) { + if (ue->ulsch[proc->thread_id][gNB_id][0]->harq_processes[harq_pid]->status == ACTIVE) + nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, proc->thread_id, gNB_id); + } - if (get_softmodem_params()->usim_test==0) { + if (get_softmodem_params()->usim_test==0) { LOG_D(PHY, "Generating PUCCH\n"); pucch_procedures_ue_nr(ue, gNB_id, proc, FALSE); - } + } LOG_D(PHY, "Sending Uplink data \n"); nr_ue_pusch_common_procedures(ue, slot_tx, &ue->frame_parms,1); - //ue->ulsch[thread_id][gNB_id][0]->harq_processes[harq_pid]->pusch_pdu.nrOfLayers); - } - //LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1); - /* RACH */ - if (get_softmodem_params()->do_ra==1) { - if ((ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) { - nr_ue_prach_procedures(ue, proc, gNB_id, mode); - } + } + + if (ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH) { + nr_ue_prach_procedures(ue, proc, gNB_id); } LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); @@ -231,35 +326,30 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } -void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0..6] - PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - uint8_t eNB_id, - uint16_t slot, // slot index of each radio frame [0..19] - runmode_t mode) -{ - LOG_D(PHY,"ue_measurement_procedures l %u Ncp %d\n",l,ue->frame_parms.Ncp); +void nr_ue_measurement_procedures(uint16_t l, + PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + uint8_t eNB_id, + uint16_t slot){ NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - int nr_tti_rx = proc->nr_tti_rx; + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); 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) + + LOG_D(PHY,"Doing UE measurement procedures in symbol l %u Ncp %d nr_slot_rx %d, rxdata %p\n", + l, + ue->frame_parms.Ncp, + nr_slot_rx, + ue->common_vars.rxdata); + + nr_ue_measurements(ue, proc, nr_slot_rx); #if T_TRACER if(slot == 0) - T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(proc->frame_rx%1024), T_INT(proc->nr_tti_rx), + T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx), T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)), T_INT((int)ue->measurements.rx_rssi_dBm[0]), T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), @@ -269,21 +359,6 @@ void nr_ue_measurement_procedures(uint16_t l, // symbol index of each slot [0 T_INT((int)ue->common_vars.freq_offset)); #endif } -#if 0 - if (l==(6-ue->frame_parms.Ncp)) { - - // make sure we have signal from PSS/SSS for N0 measurement - // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN); - ue_rrc_measurements(ue, - slot, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT); - - - } -#endif // accumulate and filter timing offset estimation every subframe (instead of every frame) if (( slot == 2) && (l==(2-frame_parms->Ncp))) { @@ -308,21 +383,16 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag) { - // int i; - //int pbch_tx_ant=0; - //uint8_t pbch_phase; int ret = 0; - //static uint8_t first_run = 1; - //uint8_t pbch_trials = 0; DevAssert(ue); int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); - //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,gNB_id); + LOG_D(PHY,"[UE %d] Frame %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,ue->frame_parms.Nid_cell,gNB_id); ret = nr_rx_pbch(ue, proc, ue->pbch_vars[gNB_id], @@ -338,24 +408,38 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){ - ue->UE_mode[gNB_id] = PRACH; - ue->prach_resources[gNB_id]->sync_frame = frame_rx; - ue->prach_resources[gNB_id]->init_msg1 = 0; + if (get_softmodem_params()->do_ra) { + ue->UE_mode[gNB_id] = PRACH; + ue->prach_resources[gNB_id]->sync_frame = frame_rx; + ue->prach_resources[gNB_id]->init_msg1 = 0; + } else { + ue->UE_mode[gNB_id] = PUSCH; + } } #ifdef DEBUG_PHY_PROC uint16_t frame_tx; - LOG_D(PHY,"[UE %d] frame %d, nr_tti_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", + LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", ue->Mod_id, frame_rx, - nr_tti_rx, + nr_slot_rx, frame_tx, ue->frame_parms.N_RB_DL); #endif } else { - LOG_E(PHY,"[UE %d] frame %d, nr_tti_rx %d, Error decoding PBCH!\n", - ue->Mod_id,frame_rx, nr_tti_rx); + LOG_E(PHY,"[UE %d] frame %d, nr_slot_rx %d, Error decoding PBCH!\n", + ue->Mod_id,frame_rx, nr_slot_rx); + /*FILE *fd; + if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) { + fwrite((void *)&ue->common_vars.rxdata[0][0], + sizeof(int32_t), + ue->frame_parms.samples_per_frame, + fd); + LOG_I(PHY,"Dummping Frame ... bye bye \n"); + fclose(fd); + exit(0); + }*/ /* write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_subframe,1,1); @@ -387,7 +471,7 @@ void nr_ue_pbch_procedures(uint8_t gNB_id, #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", - ue->Mod_id,frame_rx, nr_tti_rx, + ue->Mod_id,frame_rx, nr_slot_rx, ue->pbch_vars[gNB_id]->pdu_errors, ue->pbch_vars[gNB_id]->pdu_errors_conseq); #endif @@ -420,8 +504,10 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, UE_nr_rxtx_proc_t *proc) { int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; unsigned int dci_cnt=0; + fapi_nr_dci_indication_t dci_ind = {0}; + nr_downlink_indication_t dl_indication; /* // unsigned int dci_cnt=0, i; //removed for nr_ue_pdcch_procedures and added in the loop for nb_coreset_active @@ -430,10 +516,10 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, #endif int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_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 next1_thread_id = proc->thread_id== (RX_NB_TH-1) ? 0:(proc->thread_id+1); //uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); @@ -444,8 +530,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, uint8_t dci_fields_sizes_cnt[MAX_NR_DCI_DECODED_SLOT][NBR_NR_DCI_FIELDS][NBR_NR_FORMATS]; int nb_searchspace_active=0; - NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]]; - NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]; + NR_UE_PDCCH **pdcch_vars = ue->pdcch_vars[proc->thread_id]; + NR_UE_PDCCH *pdcch_vars2 = ue->pdcch_vars[proc->thread_id][gNB_id]; // s in TS 38.212 Subclause 10.1, for each active BWP the UE can deal with 10 different search spaces // Higher layers have updated the number of searchSpaces with are active in the current slot and this value is stored in variable nb_searchspace_total int nb_searchspace_total = pdcch_vars2->nb_search_space; @@ -467,7 +553,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, #ifdef NR_PDCCH_SCHED_DEBUG printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> there is a bug in FAPI to calculate nb_searchspace_total so we set it to 1...\n"); printf("<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> the number of searchSpaces active in the current slot(%d) is %d) \n", - nr_tti_rx,nb_searchspace_total); + nr_slot_rx,nb_searchspace_total); #endif //FK: we define dci_ind and dl_indication as local variables, this way the call to the mac should be thread safe @@ -491,12 +577,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, // The following code has been removed as it is handled by higher layers (fapi) // - // Verify that monitoring is required at the slot nr_tti_rx. We will run pdcch procedure only if do_pdcch_monitoring_current_slot=1 + // Verify that monitoring is required at the slot nr_slot_rx. We will run pdcch procedure only if do_pdcch_monitoring_current_slot=1 // For Type0-PDCCH searchspace, we need to calculate the monitoring slot from Tables 13-1 .. 13-15 in TS 38.213 Subsection 13 //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) { + //} else if (nr_slot_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 //} @@ -515,7 +601,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, #endif // if (do_pdcch_monitoring_current_slot) { - // the searchSpace indicates that we need to monitor PDCCH in current nr_tti_rx + // the searchSpace indicates that we need to monitor PDCCH in current nr_slot_rx // get the parameters describing the current SEARCHSPACE // the CORESET id applicable to the current SearchSpace //int searchSpace_coreset_id = pdcch_vars2->searchSpace[nb_searchspace_active].controlResourceSetId; @@ -588,8 +674,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, searchSpaceType); #endif nr_rx_pdcch(ue, - proc->frame_rx, - nr_tti_rx, + frame_rx, + nr_slot_rx, gNB_id, //(ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI, SISO, @@ -607,9 +693,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, */ 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); + nr_rx_pdcch(ue, proc); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); @@ -620,29 +704,24 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, pdcch_vars->nb_search_space); #endif - fapi_nr_dci_indication_t dci_ind={0}; - nr_downlink_indication_t dl_indication={0}; - dci_cnt = nr_dci_decoding_procedure(ue, - proc->frame_rx, - nr_tti_rx, - &dci_ind); + dci_cnt = nr_dci_decoding_procedure(ue, proc, &dci_ind); #ifdef NR_PDCCH_SCHED_DEBUG LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt); #endif 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); + //LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_slot_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_slot_rx); for (int i=0; i rnti %x : format %d\n", - ue->Mod_id,frame_rx%1024,nr_tti_rx,nr_mode_string[ue->UE_mode[gNB_id]], + ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]], i + 1, dci_cnt, dci_ind.dci_list[i].rnti, dci_ind.dci_list[i].dci_format); } - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dci_received += dci_cnt; + ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt; dci_ind.number_of_dcis = dci_cnt; /* @@ -664,7 +743,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, &dci_ind.dci_list[i].dci, dci_fields_sizes_cnt[i], dci_alloc_rx[i].format, - nr_tti_rx, + nr_slot_rx, pdcch_vars2->n_RB_BWP[nb_searchspace_active], pdcch_vars2->n_RB_BWP[nb_searchspace_active], crc_scrambled_values); @@ -682,14 +761,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, */ // fill dl_indication message - dl_indication.module_id = ue->Mod_id; - dl_indication.cc_id = ue->CC_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 - dl_indication.dci_ind = &dci_ind; - + nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, gNB_id); // send to mac ue->if_inst->dl_indication(&dl_indication, NULL); @@ -704,7 +776,8 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, int nr_ue_pdsch_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 nr_tti_rx = proc->nr_tti_rx; + int frame_rx = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; int m; int i_mod,eNB_id_i,dual_stream_UE; int first_symbol_flag=0; @@ -716,70 +789,82 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ if (!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; + NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid]; + uint16_t BWPStart = dlsch0_harq->BWPStart; + uint16_t pdsch_start_rb = dlsch0_harq->start_rb; + uint16_t pdsch_nb_rb = dlsch0_harq->nb_rb; + uint16_t s0 = dlsch0_harq->start_symbol; + uint16_t s1 = dlsch0_harq->nb_symbols; - LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d (%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,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); + LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); - // do channel estimation for first DMRS only - for (m = s0; m < 3; m++) { + for (m = s0; m < (s0 +s1); 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+(BWPStart + pdsch_start_rb)*12, - pdsch_nb_rb); - LOG_D(PHY,"Channel Estimation in symbol %d\n",m); - break; + for (uint8_t aatx=0; aatx<1; aatx++) {//for MIMO Config: it shall loop over no_layers + nr_pdsch_channel_estimation(ue, + proc, + 0 /*eNB_id*/, + nr_slot_rx, + aatx /*p*/, + m, + BWPStart, + ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12, + pdsch_nb_rb); + LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m); +#if 0 + ///LOG_M: the channel estimation + int nr_frame_rx = proc->frame_rx; + char filename[100]; + for (uint8_t aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { + sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx); + int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates; + LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); + } +#endif + } + if ( ue->high_speed_flag == 0 ) //for slow speed case only estimate the channel once per slot + break; } } + + uint16_t first_symbol_with_data = s0; + uint32_t dmrs_data_re; + + if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) + dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups; + else + dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups; + + while ((dmrs_data_re == 0) && (dlsch0_harq->dlDmrsSymbPos & (1 << first_symbol_with_data))) { + first_symbol_with_data++; + } + for (m = s0; m < (s1 + s0); m++) { dual_stream_UE = 0; eNB_id_i = eNB_id+1; i_mod = 0; - - if ((m==s0) && (m<3)) - first_symbol_flag = 1; + if (( m==first_symbol_with_data ) && (m<4)) + first_symbol_flag = 1; else - first_symbol_flag = 0; + first_symbol_flag = 0; + #if UE_TIMING_TRACE uint8_t slot = 0; 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]); + start_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #endif // process DLSCH received in first slot // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) { - if (nr_rx_pdsch(ue, - pdsch, - eNB_id, - eNB_id_i, - proc->frame_rx, - nr_tti_rx, // nr_tti_rx, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid) < 0) - return -1; - } - else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) - if (pdsch == RA_PDSCH) ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]=ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m-1]; - else if (pdsch == PDSCH) { - if (nr_rx_pdsch(ue, + if (nr_rx_pdsch(ue, + proc, pdsch, eNB_id, eNB_id_i, - proc->frame_rx, - nr_tti_rx, // nr_tti_rx, + frame_rx, + nr_slot_rx, m, first_symbol_flag, dual_stream_UE, @@ -787,15 +872,32 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ dlsch0->current_harq_pid) < 0) return -1; } - else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n"); + else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) + if (pdsch == RA_PDSCH) ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]=ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m-1]; + else if (pdsch == PDSCH || pdsch == SI_PDSCH) { + if (nr_rx_pdsch(ue, + proc, + pdsch, + eNB_id, + eNB_id_i, + frame_rx, + nr_slot_rx, + m, + first_symbol_flag, + dual_stream_UE, + i_mod, + dlsch0->current_harq_pid) < 0) + return -1; + } + else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n"); } - if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]); + if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[proc->thread_id][eNB_id]->llr_offset[m]); #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]); + stop_meas(&ue->dlsch_llr_stats_parallelization[proc->thread_id][slot]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,nr_tti_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,nr_tti_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",frame_rx,nr_slot_rx,m,ue->dlsch_llr_stats_parallelization[proc->thread_id][slot].p_time/(cpuf*1000.0)); #endif #endif @@ -808,85 +910,6 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ return 0; } -// WIP fix: -// - time domain indication hardcoded to 0 for k2 offset -// - extend TS 38.213 ch 8.3 Msg3 PUSCH -// - b buffer -// - ulsch power offset -// - UE_mode == PUSCH case (should be handled by TA updates) -// - harq -// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures -void nr_process_rar(nr_downlink_indication_t *dl_info) { - - module_id_t module_id = dl_info->module_id; - int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command; - uint8_t gNB_index = dl_info->gNB_index; // *rar; - PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id]; - NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index]; - UE_MODE_t UE_mode = ue->UE_mode[gNB_index]; - NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index]; - - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", module_id, frame_rx, nr_tti_rx, UE_mode); - - if (ue->mac_enabled == 1) { - if ((UE_mode != PUSCH) && (prach_resources->Msg3 != NULL)) { - - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_tti_rx, prach_resources->ra_PreambleIndex); - - ta_command = nr_ue_process_rar(ue->Mod_id, - cc_id, - frame_rx, - nr_tti_rx, - dlsch0->harq_processes[0]->b, - &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, - prach_resources->ra_PreambleIndex, - dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload - - if (ta_command != 0xffff) { - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got Temporary C-RNTI %x and timing advance %d from RAR\n", - ue->Mod_id, - frame_rx, - nr_tti_rx, - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, - ta_command); - - nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); - - if (ue->mode != debug_prach) - ue->UE_mode[gNB_index] = RA_RESPONSE; - - } else { - LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", ue->Mod_id, prach_resources->ra_PreambleIndex); - } - } - } else { - // rar = dlsch0->harq_processes[0]->b+1; - // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); - // nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); - } -} - -// if contention resolution fails, go back to UE mode PRACH -void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) { - - PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; - ue->UE_mode[gNB_index] = PRACH; - - for (int i=0; i pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0; - } - LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id); -} - -void nr_ra_succeeded(uint8_t Mod_id, - uint8_t CC_id, - uint8_t gNB_index){ - LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id); - PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; - ue->ulsch_Msg3_active[gNB_index] = 0; - ue->UE_mode[gNB_index] = PUSCH; -} - void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, @@ -894,20 +917,24 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, int *dlsch_errors, - runmode_t mode) { + uint8_t dlsch_parallel) { + + if (dlsch0==NULL) + AssertFatal(0,"dlsch0 should be defined at this level \n"); int harq_pid = dlsch0->current_harq_pid; int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; int ret=0, ret1=0; NR_UE_PDSCH *pdsch_vars; uint8_t is_cw0_active = 0; uint8_t is_cw1_active = 0; uint8_t dmrs_type, nb_re_dmrs; - uint16_t length_dmrs = 1; + uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos); uint16_t nb_symb_sch = 9; nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind; + uint16_t number_pdus = 1; // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id]; uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; @@ -920,12 +947,9 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, uint16_t ofdm_symbol_size = ue->frame_parms.ofdm_symbol_size; uint16_t nb_prefix_samples = ue->frame_parms.nb_prefix_samples; uint32_t t_subframe = 1; // subframe duration of 1 msec - uint16_t bw_scaling, start_symbol; + uint16_t start_symbol; float tc_factor; - if (dlsch0==NULL) - AssertFatal(0,"dlsch0 should be defined at this level \n"); - is_cw0_active = dlsch0->harq_processes[harq_pid]->status; nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; @@ -940,8 +964,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(dlsch1) is_cw1_active = dlsch1->harq_processes[harq_pid]->status; - LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_tti_rx, harq_pid, is_cw0_active); - LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_tti_rx, harq_pid, is_cw1_active); + LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw0_active); + LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active); if(is_cw0_active && is_cw1_active) { @@ -958,7 +982,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, case RA_PDSCH: case P_PDSCH: case PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id]; break; case PMCH: case PDSCH1: @@ -979,7 +1003,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (ue->prach_resources[eNB_id]!=NULL) dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI; else { - LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_tti_rx); + LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx); //mac_xface->macphy_exit("prach_resources is NULL"); return; } @@ -993,7 +1017,7 @@ 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, - length_dmrs, + dmrs_len, dlsch0->harq_processes[harq_pid]->Qm, dlsch0->harq_processes[harq_pid]->Nl); #if UE_TIMING_TRACE @@ -1011,22 +1035,23 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, #endif #if 0 - LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, nr_tti_rx, harq_pid); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch0->Kmimo); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_tti_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols); + LOG_I(PHY," ------ start ldpc decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, nr_slot_rx, harq_pid); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols); #endif #if UE_TIMING_TRACE - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #endif -#ifdef UE_DLSCH_PARALLELISATION - ret = nr_dlsch_decoding_mthread(ue, + if( dlsch_parallel) + { + ret = nr_dlsch_decoding_mthread(ue, proc, eNB_id, pdsch_vars->llr[0], @@ -1035,50 +1060,54 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dlsch0->harq_processes[harq_pid], frame_rx, nb_symb_sch, - nr_tti_rx, + nr_slot_rx, harq_pid, pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); - LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret = %d\n", ret); -#else - ret = nr_dlsch_decoding(ue, + LOG_T(PHY,"dlsch decoding is parallelized, ret = %d\n", ret); + } + else + { + ret = nr_dlsch_decoding(ue, + proc, + eNB_id, pdsch_vars->llr[0], &ue->frame_parms, dlsch0, dlsch0->harq_processes[harq_pid], frame_rx, nb_symb_sch, - nr_tti_rx, + nr_slot_rx, harq_pid, pdsch==PDSCH?1:0, dlsch0->harq_processes[harq_pid]->TBS>256?1:0); - LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret = %d\n", ret); - //printf("start cW0 dlsch decoding\n"); -#endif + LOG_T(PHY,"Sequential dlsch decoding , ret = %d\n", ret); + } + #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #if DISABLE_LOG_X printf(" --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); printf("AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #else LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); LOG_I(PHY, "AbsSubframe %d.%d --> LDPC Decoding for CW0 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #endif #endif if(is_cw1_active) { // start ldpc decode for CW 1 - dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb, - nb_symb_sch, - nb_re_dmrs, - length_dmrs, - dlsch1->harq_processes[harq_pid]->Qm, + dlsch1->harq_processes[harq_pid]->G = nr_get_G(dlsch1->harq_processes[harq_pid]->nb_rb, + nb_symb_sch, + nb_re_dmrs, + dmrs_len, + dlsch1->harq_processes[harq_pid]->Qm, dlsch1->harq_processes[harq_pid]->Nl); #if UE_TIMING_TRACE start_meas(&ue->dlsch_unscrambling_stats); @@ -1093,107 +1122,104 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, #endif #if 0 - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_tti_rx, harq_pid, dlsch1->Kmimo); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_tti_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->num_pdcch_symbols); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols); #endif #if UE_TIMING_TRACE - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + start_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #endif -#ifdef UE_DLSCH_PARALLELISATION - ret1 = nr_dlsch_decoding_mthread(ue, - proc, - eNB_id, - pdsch_vars->llr[1], - &ue->frame_parms, - dlsch1, - dlsch1->harq_processes[harq_pid], - frame_rx, - nb_symb_sch, - nr_tti_rx, - harq_pid, - pdsch==PDSCH?1:0, - dlsch1->harq_processes[harq_pid]->TBS>256?1:0); - LOG_T(PHY,"UE_DLSCH_PARALLELISATION is defined, ret1 = %d\n", ret1); -#else - ret1 = nr_dlsch_decoding(ue, - pdsch_vars->llr[1], - &ue->frame_parms, - dlsch1, - dlsch1->harq_processes[harq_pid], - frame_rx, - nb_symb_sch, - nr_tti_rx, - harq_pid, - pdsch==PDSCH?1:0,//proc->decoder_switch, - dlsch1->harq_processes[harq_pid]->TBS>256?1:0); - LOG_T(PHY,"UE_DLSCH_PARALLELISATION is NOT defined, ret1 = %d\n", ret1); - printf("start cw1 dlsch decoding\n"); -#endif + if(dlsch_parallel) + { + ret1 = nr_dlsch_decoding_mthread(ue, + proc, + eNB_id, + pdsch_vars->llr[1], + &ue->frame_parms, + dlsch1, + dlsch1->harq_processes[harq_pid], + frame_rx, + nb_symb_sch, + nr_slot_rx, + harq_pid, + pdsch==PDSCH?1:0, + dlsch1->harq_processes[harq_pid]->TBS>256?1:0); + LOG_T(PHY,"CW dlsch decoding is parallelized, ret1 = %d\n", ret1); + } + else + { + ret1 = nr_dlsch_decoding(ue, + proc, + eNB_id, + pdsch_vars->llr[1], + &ue->frame_parms, + dlsch1, + dlsch1->harq_processes[harq_pid], + frame_rx, + nb_symb_sch, + nr_slot_rx, + harq_pid, + pdsch==PDSCH?1:0,//proc->decoder_switch, + dlsch1->harq_processes[harq_pid]->TBS>256?1:0); + LOG_T(PHY,"CWW sequential dlsch decoding, ret1 = %d\n", ret1); + } #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]]); + stop_meas(&ue->dlsch_decoding_stats[proc->thread_id]); #if DISABLE_LOG_X printf(" --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); printf("AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #else LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); #endif #endif LOG_I(PHY,"AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", - frame_rx%1024, nr_tti_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[nr_tti_rx]].p_time)/(cpuf*1000.0)); + frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats[proc->thread_id].p_time)/(cpuf*1000.0)); LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS); } - LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_tti_rx); + LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_slot_rx); LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS); - + if(retmax_ldpc_iterations+1){ - // fill dl_indication message - dl_indication.module_id = ue->Mod_id; - dl_indication.cc_id = ue->CC_id; - dl_indication.gNB_index = eNB_id; - dl_indication.frame = frame_rx; - dl_indication.slot = nr_tti_rx; - dl_indication.rx_ind = &rx_ind; // hang on rx_ind instance - dl_indication.proc=proc; - - //dl_indication.rx_ind->number_pdus switch (pdsch) { case RA_PDSCH: - rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR; - break; + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, eNB_id, ue, dlsch0, number_pdus); + + ue->UE_mode[eNB_id] = RA_RESPONSE; + break; case PDSCH: - rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH; - break; + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus); + break; + case SI_PDSCH: + rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB; + break; default: - break; + break; } - 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; + LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->harq_processes[harq_pid]->TBS, dlsch0->harq_processes[harq_pid]->TBS / 8); - //ue->dl_indication.rx_ind = &dlsch1->harq_processes[harq_pid]->b; //no data, only dci for now - dl_indication.dci_ind = NULL; //&ue->dci_ind; // send to mac - if (ue->if_inst && ue->if_inst->dl_indication) - ue->if_inst->dl_indication(&dl_indication, ul_time_alignment); + if (ue->if_inst && ue->if_inst->dl_indication) { + ue->if_inst->dl_indication(&dl_indication, ul_time_alignment); + } } // TODO CRC check for CW0 @@ -1204,7 +1230,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(dlsch0->rnti != 0xffff){ LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, + harq_pid,frame_rx,nr_slot_rx, dlsch0->harq_processes[harq_pid]->rvidx, dlsch0->harq_processes[harq_pid]->round, dlsch0->harq_processes[harq_pid]->mcs, @@ -1214,7 +1240,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(dlsch0->rnti != 0xffff){ LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, + harq_pid,frame_rx,nr_slot_rx, dlsch0->harq_processes[harq_pid]->rvidx, dlsch0->harq_processes[harq_pid]->round, dlsch0->harq_processes[harq_pid]->mcs, @@ -1231,16 +1257,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (ue->mac_enabled == 1) { - // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size - switch (ue->frame_parms.N_RB_DL) { - case 32: bw_scaling = 4; break; - case 66: bw_scaling = 8; break; - case 106: bw_scaling = 16; break; - case 217: bw_scaling = 32; break; - case 245: bw_scaling = 32; break; - case 273: bw_scaling = 32; break; - default: abort(); - } + uint16_t bw_scaling = get_bw_scaling(ue->frame_parms.N_RB_DL); /* Time Alignment procedure // - UE processing capability 1 @@ -1298,15 +1315,15 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ul_tx_timing_adjustment = 1 + ceil(slots_per_subframe*((N_t_1 + N_t_2 + N_TA_max)*tc_factor + 0.5)/t_subframe); if (ul_time_alignment->apply_ta == 1){ - ul_time_alignment->ta_slot = (nr_tti_rx + ul_tx_timing_adjustment) % slots_per_frame; - if (nr_tti_rx + ul_tx_timing_adjustment > slots_per_frame){ + ul_time_alignment->ta_slot = (nr_slot_rx + ul_tx_timing_adjustment) % slots_per_frame; + if (nr_slot_rx + ul_tx_timing_adjustment > slots_per_frame){ ul_time_alignment->ta_frame = (frame_rx + 1) % 1024; } else { ul_time_alignment->ta_frame = frame_rx; } // reset TA flag ul_time_alignment->apply_ta = 0; - LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_tti_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); + LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_slot_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot); } } @@ -1335,17 +1352,10 @@ void *UE_thread_slot1_dl_processing(void *arg) { UE_nr_rxtx_proc_t *proc = rtd->proc; PHY_VARS_NR_UE *ue = rtd->UE; - int frame_rx; - uint8_t nr_tti_rx; - uint8_t pilot0; uint8_t pilot1; - uint8_t slot1; - - uint8_t next_nr_tti_rx; - uint8_t next_subframe_slot0; proc->instance_cnt_slot1_dl_processing=-1; - proc->nr_tti_rx=proc->sub_frame_start; + proc->nr_slot_rx = proc->sub_frame_start * ue->frame_parms.slots_per_subframe; char threadname[256]; sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start); @@ -1354,9 +1364,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { CPU_ZERO(&cpuset); if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 ) CPU_SET(threads.slot1_proc_one, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) + if ( RX_NB_TH > 1 && (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) CPU_SET(threads.slot1_proc_two, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) + if ( RX_NB_TH > 2 && (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) CPU_SET(threads.slot1_proc_three, &cpuset); init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, @@ -1376,21 +1386,15 @@ void *UE_thread_slot1_dl_processing(void *arg) { exit_fun("nothing to add"); } - /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++) - { - frame_rx = ue->proc.proc_rxtx[0].frame_rx; - nr_tti_rx = ue->proc.proc_rxtx[0].nr_tti_rx; - printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_tti_rx); - }*/ - frame_rx = proc->frame_rx; - nr_tti_rx = proc->nr_tti_rx; - next_nr_tti_rx = (1+nr_tti_rx)%10; - next_subframe_slot0 = next_nr_tti_rx<<1; + int frame_rx = proc->frame_rx; + uint8_t subframe_rx = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe; + uint8_t next_subframe_rx = (1 + subframe_rx) % NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + uint8_t next_subframe_slot0 = next_subframe_rx * ue->frame_parms.slots_per_subframe; - slot1 = (nr_tti_rx<<1) + 1; - pilot0 = 0; + uint8_t slot1 = proc->nr_slot_rx + 1; + uint8_t pilot0 = 0; - //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_tti_rx); + //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, nr_slot_rx); if (ue->frame_parms.Ncp == 0) { // normal prefix pilot1 = 4; @@ -1400,13 +1404,13 @@ void *UE_thread_slot1_dl_processing(void *arg) { /**** Slot1 FE Processing ****/ #if UE_TIMING_TRACE - start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + start_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]); #endif // I- start dl slot1 processing - // do first symbol of next downlink nr_tti_rx for channel estimation + // do first symbol of next downlink nr_slot_rx for channel estimation /* - // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next nr_tti_rx ofdmSym11) - if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL) + // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next nr_slot_rx ofdmSym11) + if (nr_subframe_select(&ue->frame_parms,next_nr_slot_rx) != SF_UL) { front_end_fft(ue, pilot0, @@ -1430,7 +1434,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { start_meas(&ue->ofdm_demod_stats); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,l); + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l); front_end_fft(ue, l, slot1, @@ -1443,9 +1447,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { } } // for l=1..l2 - if (nr_subframe_select(&ue->frame_parms,next_nr_tti_rx) != SF_UL) + if (nr_subframe_select(&ue->frame_parms,next_nr_slot_rx) != SF_UL) { - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_tti_rx,next_subframe_slot0,pilot0); + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,nr_slot_rx,next_subframe_slot0,pilot0); front_end_fft(ue, pilot0, next_subframe_slot0, @@ -1467,37 +1471,37 @@ void *UE_thread_slot1_dl_processing(void *arg) { } //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait); } - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,slot1,l); + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_slot_rx,slot1,l); front_end_chanEst(ue, l, slot1, 0); - ue_measurement_procedures(l-1,ue,proc,0,1+(nr_tti_rx<<1),0,ue->mode); + ue_measurement_procedures(l-1,ue,proc,0,slot1,0,ue->mode); } - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_tti_rx,next_subframe_slot0,pilot0); + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,nr_slot_rx,next_subframe_slot0,pilot0); front_end_chanEst(ue, pilot0, next_subframe_slot0, 0); - if ( (nr_tti_rx == 0) && (ue->decode_MIB == 1)) + if ( (nr_slot_rx == 0) && (ue->decode_MIB == 1)) { ue_pbch_procedures(0,ue,proc,0); } proc->chan_est_slot1_available = 1; - //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx); - //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_tti_rx); + //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx); + //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx); - //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_tti_rx); + //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->nr_slot_rx); #if UE_TIMING_TRACE - stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + stop_meas(&ue->ue_front_end_per_slot_stat[proc->thread_id][1]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_tti_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,nr_slot_rx,ue->ue_front_end_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #endif #endif @@ -1509,22 +1513,22 @@ void *UE_thread_slot1_dl_processing(void *arg) { usleep(1); wait++; } - //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_tti_rx,wait); + //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,nr_slot_rx,wait); /**** Pdsch Procedure Slot1 ****/ // start slot1 thread for Pdsch Procedure (slot1) // do procedures for C-RNTI - //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_tti_rx); + //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,nr_slot_rx); #if UE_TIMING_TRACE - start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + start_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]); #endif // start slave thread for Pdsch Procedure (slot1) // do procedures for C-RNTI uint8_t eNB_id = 0; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) { //wait until first ofdm symbol is processed //wait = 0; //while(proc->first_symbol_available == 0) @@ -1532,20 +1536,20 @@ void *UE_thread_slot1_dl_processing(void *arg) { // usleep(1); // wait++; //} - //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,nr_tti_rx,wait); + //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,nr_slot_rx,wait); //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, - ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0], + ue->dlsch[proc->thread_id][eNB_id][0], NULL, (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); + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_slot_rx); + LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, nr_slot_rx); } // do procedures for SI-RNTI @@ -1574,7 +1578,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { abstraction_flag); } // do procedures for RA-RNTI - if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { + if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1) && (UE_mode != PUSCH)) { ue_pdsch_procedures(ue, proc, eNB_id, @@ -1587,14 +1591,14 @@ void *UE_thread_slot1_dl_processing(void *arg) { } proc->llr_slot1_available=1; - //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_tti_rx); + //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,nr_slot_rx); #if UE_TIMING_TRACE - stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1]); + stop_meas(&ue->pdsch_procedures_per_slot_stat[proc->thread_id][1]); #if DISABLE_LOG_X - printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_tti_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[nr_tti_rx]][1].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,nr_slot_rx,ue->pdsch_procedures_per_slot_stat[proc->thread_id][1].p_time/(cpuf*1000.0)); #endif #endif @@ -1614,6 +1618,59 @@ void *UE_thread_slot1_dl_processing(void *arg) { } #endif +int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp) +{ + int mu = fp->numerology_index; + //uint8_t half_frame_index = fp->half_frame_bit; + //uint8_t i_ssb = fp->ssb_index; + uint8_t Lmax = fp->Lmax; + + if (!(frame%(1<<(config->ssb_table.ssb_period-1)))){ + + if(Lmax <= 8) { + if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000)) + return 1; + else return 0; + + } + else if(Lmax == 64) { + if (mu == NR_MU_3){ + + if (slot>=0 && slot <= 7){ + if(((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else if (slot>=10 && slot <=17){ + if(((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*(slot-2))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*(slot-2) +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else if (slot>=20 && slot <=27){ + if(((config->ssb_table.ssb_mask_list[1].ssb_mask << 2*(slot-20))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[1].ssb_mask << (2*(slot-20) +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else if (slot>=30 && slot <=37){ + if(((config->ssb_table.ssb_mask_list[1].ssb_mask << 2*(slot-22))&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[1].ssb_mask << (2*(slot-22) +1))&0x80000000) == 0x80000000) + return 1; + else return 0; + } + else return 0; + + } + + + else if (mu == NR_MU_4) { + AssertFatal(0==1, "not implemented for mu = %d yet\n", mu); + } + else AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu); + } + else AssertFatal(0==1, "Invalid Lmax %u for the synchronization block\n", Lmax); + } + else return 0; + +} int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp) { @@ -1639,26 +1696,26 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, - runmode_t mode) -{ + uint8_t dlsch_parallel + ) +{ int frame_rx = proc->frame_rx; - int nr_tti_rx = proc->nr_tti_rx; + int nr_slot_rx = proc->nr_slot_rx; int slot_pbch; - NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][0]; + int slot_ssb; + NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][0]; fapi_nr_config_request_t *cfg = &ue->nrUE_config; uint8_t nb_symb_pdcch = pdcch_vars->nb_search_space > 0 ? pdcch_vars->pdcch_config[0].coreset.duration : 0; uint8_t dci_cnt = 0; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - - NR_UE_MAC_INST_t *mac = get_mac_inst(0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); - LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_slot_rx); /* - 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 next1_thread_id = proc->thread_id== (RX_NB_TH-1) ? 0:(proc->thread_id+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); */ @@ -1667,96 +1724,111 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, 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(cfg, frame_rx, nr_tti_rx, fp); + + slot_pbch = is_pbch_in_slot(cfg, frame_rx, nr_slot_rx, fp); + slot_ssb = is_ssb_in_slot(cfg, frame_rx, nr_slot_rx, fp); // looking for pbch only in slot where it is supposed to be - if ((ue->decode_MIB == 1) && slot_pbch) - { - LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - for (int i=1; i<4; i++) { + if (slot_ssb) { + LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); + for (int i=1; i<4; i++) { - nr_slot_fep(ue, - (ue->symbol_offset+i)%(fp->symbols_per_slot), - nr_tti_rx, - 0, - 0); + nr_slot_fep(ue, + proc, + (ue->symbol_offset+i)%(fp->symbols_per_slot), + nr_slot_rx, + 0, + 0); #if UE_TIMING_TRACE - start_meas(&ue->dlsch_channel_estimation_stats); + start_meas(&ue->dlsch_channel_estimation_stats); #endif - nr_pbch_channel_estimation(ue,0,nr_tti_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); + nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_channel_estimation_stats); + stop_meas(&ue->dlsch_channel_estimation_stats); #endif - - } - - //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ - nr_ue_rsrp_measurements(ue,nr_tti_rx,0); - //} - + } + nr_ue_rsrp_measurements(ue, gNB_id, proc, nr_slot_rx, 0); + + if ((ue->decode_MIB == 1) && slot_pbch) { + + LOG_D(PHY," ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); nr_ue_pbch_procedures(gNB_id, ue, proc, 0); 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); + LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); nr_adjust_synch_ue(fp, ue, gNB_id, frame_rx, - nr_tti_rx, + nr_slot_rx, 0, 16384); } + + LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); + nr_ue_rrc_measurements(ue, proc, nr_slot_rx); } + } + + if ((frame_rx%64 == 0) && (nr_slot_rx==0)) { + printf("============================================\n"); + LOG_I(PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]); + printf("============================================\n"); + } #ifdef NR_PDCCH_SCHED nr_gold_pdcch(ue, 0, 2); - LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); for (uint16_t l=0; lofdm_demod_stats); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); nr_slot_fep(ue, + proc, l, - nr_tti_rx, + nr_slot_rx, 0, 0); + dci_cnt = 0; + for(int n_ss = 0; n_ssnb_search_space; n_ss++) { + // 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", - fp->first_carrier_offset,pdcch_vars->pdcch_config[0].BWPStart,coreset_start_rb); + LOG_D(PHY, "pdcch_channel_estimation: first_carrier_offset %d, BWPStart %d, coreset_start_rb %d\n", + fp->first_carrier_offset, pdcch_vars->pdcch_config[n_ss].BWPStart, coreset_start_rb); + if (coreset_nb_rb > 0) nr_pdcch_channel_estimation(ue, - 0, - nr_tti_rx, - l, - fp->first_carrier_offset+(pdcch_vars->pdcch_config[0].BWPStart + coreset_start_rb)*12, - coreset_nb_rb); - + proc, + 0, + nr_slot_rx, + l, + fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].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 stop_meas(&ue->ofdm_demod_stats); #endif - - //printf("phy procedure pdcch start measurement l =%d\n",l); - //nr_ue_measurement_procedures(l,ue,proc,gNB_id,(nr_tti_rx),mode); - - } - dci_cnt = nr_ue_pdcch_procedures(gNB_id, ue, proc); + dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc); + } + } if (dci_cnt > 0) { - LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_tti_rx, dci_cnt); + LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); NR_UE_DLSCH_t *dlsch = NULL; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active == 1){ - dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]; + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1){ + dlsch = ue->dlsch[proc->thread_id][gNB_id][0]; + } else if (ue->dlsch_SI[0]->active == 1){ + dlsch = ue->dlsch_SI[0]; } else if (ue->dlsch_ra[0]->active == 1){ dlsch = ue->dlsch_ra[0]; } @@ -1768,24 +1840,25 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, uint16_t start_symb_sch = dlsch0_harq->start_symbol; int symb_dmrs = -1; - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); //to update from pdsch config 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); + LOG_D(PHY,"Initializing dmrs for slot %d DMRS mask %x\n", nr_slot_rx, dlsch0_harq->dlDmrsSymbPos); + nr_gold_pdsch(ue, nr_slot_rx, 0); for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ nr_slot_fep(ue, - m, //to be updated from higher layer - nr_tti_rx, - 0, - 0); + proc, + m, //to be updated from higher layer + nr_slot_rx, + 0, + 0); } } } else { - LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_tti_rx); + LOG_D(PHY,"[UE %d] Frame %d, nr_slot_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_slot_rx); } #endif //NR_PDCCH_SCHED @@ -1795,69 +1868,77 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, #endif // do procedures for C-RNTI int ret_pdsch = 0; - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ret_pdsch = nr_ue_pdsch_procedures(ue, proc, gNB_id, PDSCH, - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0], + ue->dlsch[proc->thread_id][gNB_id][0], NULL); - //printf("phy procedure pdsch start measurement\n"); - nr_ue_measurement_procedures(2,ue,proc,gNB_id,nr_tti_rx,mode); - - /* - write_output("rxF.m","rxF",&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],fp->ofdm_symbol_size*14,1,1); - write_output("rxF_ch.m","rxFch",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dl_ch_estimates[0][0],fp->ofdm_symbol_size*14,1,1); - write_output("rxF_ch_ext.m","rxFche",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->dl_ch_estimates_ext[0][2*50*12],50*12,1,1); - write_output("rxF_ext.m","rxFe",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->rxdataF_ext[0][0],50*12*14,1,1); - write_output("rxF_comp.m","rxFc",&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->rxdataF_comp0[0][0],fp->N_RB_DL*12*14,1,1); - write_output("rxF_llr.m","rxFllr",ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][gNB_id]->llr[0],(nb_symb_sch-1)*50*12+50*6,1,0); - */ - - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx); } // do procedures for SI-RNTI if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - SI_PDSCH, - ue->dlsch_SI[gNB_id], - NULL); + proc, + gNB_id, + SI_PDSCH, + ue->dlsch_SI[gNB_id], + NULL); + nr_ue_dlsch_procedures(ue, + proc, + gNB_id, + SI_PDSCH, + ue->dlsch_SI[gNB_id], + NULL, + &ue->dlsch_SI_errors[gNB_id], + dlsch_parallel); + + // deactivate dlsch once dlsch proc is done + ue->dlsch_SI[gNB_id]->active = 0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); } - // do procedures for SI-RNTI + // do procedures for P-RNTI if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - P_PDSCH, - ue->dlsch_p[gNB_id], - NULL); + proc, + gNB_id, + P_PDSCH, + ue->dlsch_p[gNB_id], + NULL); + + nr_ue_dlsch_procedures(ue, + proc, + gNB_id, + P_PDSCH, + ue->dlsch_p[gNB_id], + NULL, + &ue->dlsch_p_errors[gNB_id], + dlsch_parallel); + + // deactivate dlsch once dlsch proc is done + ue->dlsch_p[gNB_id]->active = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); } // do procedures for RA-RNTI - if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1)) { + if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1) && (ue->UE_mode[gNB_id] != PUSCH)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - RA_PDSCH, - ue->dlsch_ra[gNB_id], - NULL); - - // #if UE_TIMING_TRACE - // start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); - // #endif + proc, + gNB_id, + RA_PDSCH, + ue->dlsch_ra[gNB_id], + NULL); nr_ue_dlsch_procedures(ue, proc, @@ -1866,30 +1947,22 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, ue->dlsch_ra[gNB_id], NULL, &ue->dlsch_ra_errors[gNB_id], - mode); + dlsch_parallel); - // #if UE_TIMING_TRACE - // stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); - #if DISABLE_LOG_X - printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); - printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); - #else - LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); - LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); - #endif - // #endif + // deactivate dlsch once dlsch proc is done + ue->dlsch_ra[gNB_id]->active = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } // do procedures for C-RNTI - if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { - LOG_D(PHY, "DLSCH data reception at nr_tti_rx: %d \n \n", nr_tti_rx); + LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d \n \n", nr_slot_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); #if UE_TIMING_TRACE - start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + start_meas(&ue->dlsch_procedures_stat[proc->thread_id]); #endif if (ret_pdsch >= 0) @@ -1897,26 +1970,26 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, proc, gNB_id, PDSCH, - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0], - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][1], + ue->dlsch[proc->thread_id][gNB_id][0], + ue->dlsch[proc->thread_id][gNB_id][1], &ue->dlsch_errors[gNB_id], - mode); + dlsch_parallel); #if UE_TIMING_TRACE - stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + stop_meas(&ue->dlsch_procedures_stat[proc->thread_id]); #if DISABLE_LOG_X - printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); - printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); #else - LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_tti_rx,ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); - LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_tti_rx,ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",nr_slot_rx,ue->pdsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat[proc->thread_id].p_time/(cpuf*1000.0)); #endif #endif // deactivate dlsch once dlsch proc is done - ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->active = 0; + ue->dlsch[proc->thread_id][gNB_id][0]->active = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); @@ -1927,98 +2000,35 @@ start_meas(&ue->generic_stat); #if 0 - if(nr_tti_rx==5 && ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->current_harq_pid]->nb_rb > 20){ + if(nr_slot_rx==5 && ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid]->nb_rb > 20){ //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0); - //write_output("llr.m","llr", &ue->pdsch_vars[gNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + //write_output("llr.m","llr", &ue->pdsch_vars[proc->thread_id][gNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); + write_output("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); //write_output("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); //write_output("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*fp->ofdm_symbol_size,1,1); - write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[0][0][0],14*fp->ofdm_symbol_size,1,1); - write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1); - write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1); - //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1); - //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1); + write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].dl_ch_estimates[0][0][0],14*fp->ofdm_symbol_size,1,1); + write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates_ext[0][0],14*fp->N_RB_DL*12,1,1); + write_output("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[proc->thread_id][gNB_id]->rxdataF_comp0[0][0],14*fp->N_RB_DL*12,1,1); + //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_mag0[0][0],14*fp->N_RB_DL*12,1,1); + //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_magb0[0][0],14*fp->N_RB_DL*12,1,1); AssertFatal (0,""); } #endif - // do procedures for SI-RNTI - if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) { - nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - SI_PDSCH, - ue->dlsch_SI[gNB_id], - NULL); - - /*ue_dlsch_procedures(ue, - proc, - gNB_id, - SI_PDSCH, - ue->dlsch_SI[gNB_id], - NULL, - &ue->dlsch_SI_errors[gNB_id], - mode, - abstraction_flag); - ue->dlsch_SI[gNB_id]->active = 0;*/ - } - - // do procedures for P-RNTI - if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) { - nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - P_PDSCH, - ue->dlsch_p[gNB_id], - NULL); - - - /*ue_dlsch_procedures(ue, - proc, - gNB_id, - P_PDSCH, - ue->dlsch_p[gNB_id], - NULL, - &ue->dlsch_p_errors[gNB_id], - mode, - abstraction_flag);*/ - ue->dlsch_p[gNB_id]->active = 0; - } - // do procedures for RA-RNTI - if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1)) { - nr_ue_pdsch_procedures(ue, - proc, - gNB_id, - RA_PDSCH, - ue->dlsch_ra[gNB_id], - NULL); - - /*ue_dlsch_procedures(ue, - proc, - gNB_id, - RA_PDSCH, - ue->dlsch_ra[gNB_id], - NULL, - &ue->dlsch_ra_errors[gNB_id], - mode, - abstraction_flag);*/ - ue->dlsch_ra[gNB_id]->active = 0; - } - // duplicate harq structure - /* - uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->current_harq_pid; - NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->harq_processes[current_harq_pid]; +/* + uint8_t current_harq_pid = ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid; + NR_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[current_harq_pid]; NR_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[next1_thread_id][gNB_id][0]->harq_processes[current_harq_pid]; NR_DL_UE_HARQ_t *harq_processes_dest1 = ue->dlsch[next2_thread_id][gNB_id][0]->harq_processes[current_harq_pid]; */ - /*nr_harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[nr_tti_rx]][gNB_id][0]->harq_ack[nr_tti_rx]; - nr_harq_status_t *harq_ack_dest = &ue->dlsch[next1_thread_id][gNB_id][0]->harq_ack[nr_tti_rx]; - nr_harq_status_t *harq_ack_dest1 = &ue->dlsch[next2_thread_id][gNB_id][0]->harq_ack[nr_tti_rx]; + /*nr_harq_status_t *current_harq_ack = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_ack[nr_slot_rx]; + nr_harq_status_t *harq_ack_dest = &ue->dlsch[next1_thread_id][gNB_id][0]->harq_ack[nr_slot_rx]; + nr_harq_status_t *harq_ack_dest1 = &ue->dlsch[next2_thread_id][gNB_id][0]->harq_ack[nr_slot_rx]; */ //copy_harq_proc_struct(harq_processes_dest, current_harq_processes); @@ -2027,7 +2037,7 @@ start_meas(&ue->generic_stat); //copy_harq_proc_struct(harq_processes_dest1, current_harq_processes); //copy_ack_struct(harq_ack_dest1, current_harq_ack); -if (nr_tti_rx==9) { +if (nr_slot_rx==9) { if (frame_rx % 10 == 0) { if ((ue->dlsch_received[gNB_id] - ue->dlsch_received_last[gNB_id]) != 0) ue->dlsch_fer[gNB_id] = (100*(ue->dlsch_errors[gNB_id] - ue->dlsch_errors_last[gNB_id]))/(ue->dlsch_received[gNB_id] - ue->dlsch_received_last[gNB_id]); @@ -2064,17 +2074,17 @@ phy_procedures_emos_UE_RX(ue,slot,gNB_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); #if UE_TIMING_TRACE -stop_meas(&ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]]); +stop_meas(&ue->phy_proc_rx[proc->thread_id]); #if DISABLE_LOG_X -printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); +printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0)); #else -LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_tti_rx,ue->phy_proc_rx[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); +LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx[proc->thread_id].p_time/(cpuf*1000.0)); #endif #endif //#endif //pdsch -LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_tti_rx); +LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_slot_rx); return (0); } @@ -2083,7 +2093,7 @@ uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { - int subframe = proc->subframe_tx; + int subframe = proc->nr_slot_tx / ue->frame_parms.slots_per_subframe; int frame = proc->frame_tx; CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[gNB_id].CQI_ReportPeriodic; @@ -2105,7 +2115,7 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { - int subframe = proc->subframe_tx; + int subframe = proc->nr_slot_tx / ue->frame_parms.slots_per_subframe; int frame = proc->frame_tx; CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[gNB_id].CQI_ReportPeriodic; int log2Mri = cqirep->ri_ConfigIndex/161; @@ -2123,121 +2133,93 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, return(0); } -// WIP // todo: -// - set tx_total_RE // - power control as per 38.213 ch 7.4 -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) { +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { - int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power; // tx_amp - uint16_t /*preamble_tx = 50,*/ pathloss; + int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp uint8_t mod_id = ue->Mod_id; - UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id); NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id]; + AssertFatal(prach_resources != NULL, "ue->prach_resources[%u] == NULL\n", gNB_id); uint8_t nr_prach = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); if (ue->mac_enabled == 0){ - // prach_resources->ra_PreambleIndex = preamble_tx; + prach_resources->ra_TDD_map_index = 0; prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; prach_resources->ra_RNTI = 0x1234; nr_prach = 1; - } else { - // ask L2 for RACH transport - if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) { - LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx); - // flush Msg3 Buffer - if (prach_resources->Msg3 == NULL){ - for(int i = 0; iulsch_Msg3_active[i] = 0; - } - } - nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx); - } - } - - if (!prach_resources->init_msg1 && (frame_tx > ue->prach_resources[gNB_id]->sync_frame + 150)){ - ue->prach_cnt = 0; prach_resources->init_msg1 = 1; + + } else { + + LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources\n", __FUNCTION__, frame_tx, nr_slot_tx); + nr_prach = nr_ue_get_rach(prach_resources, &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx); + } - if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) { + if (nr_prach == 1) { - pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); - LOG_D(PHY,"runmode %d\n",runmode); + if (ue->mac_enabled == 1) { + int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); + int16_t ra_preamble_rx_power = (int16_t)(10*log10(pow(10, (double)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER)/10) + pow(10, (double)(pathloss)/10))); + ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); - if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) { - ue->tx_power_dBm[nr_tti_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss; + LOG_I(PHY,"[UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n", + mod_id, + frame_tx, + nr_slot_tx, + prach_resources->ra_PreambleIndex, + pathloss, + ue->tx_power_dBm[nr_slot_tx], + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER, + prach_resources->ra_RNTI); } - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x\n", - ue->Mod_id, - frame_tx, - nr_tti_tx, - prach_resources->ra_PreambleIndex, - pathloss, - ue->tx_power_dBm[nr_tti_tx], - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER, - prach_resources->ra_RNTI); - - //ue->tx_total_RE[nr_tti_tx] = 96; // todo ue->prach_vars[gNB_id]->amp = AMP; /* #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL); + tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_slot_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL); if (tx_amp != -1) ue->prach_vars[gNB_id]->amp = tx_amp; #else ue->prach_vars[gNB_id]->amp = AMP; #endif */ - if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) - LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : PRACH TX power %d dBm, amp %d\n", ue->Mod_id, - proc->frame_rx, - proc->nr_tti_tx, - ue->tx_power_dBm[nr_tti_tx], - ue->prach_vars[gNB_id]->amp); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); - prach_power = generate_nr_prach(ue, gNB_id, nr_tti_tx); + prach_power = generate_nr_prach(ue, gNB_id, nr_slot_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); - LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", - ue->Mod_id, - pathloss, - ue->tx_power_dBm[nr_tti_tx], + LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generated PRACH Msg1 (TX power PRACH %d dBm, digital power %d dBW (amp %d)\n", + __FUNCTION__, + mod_id, + frame_tx, + nr_slot_tx, + ue->tx_power_dBm[nr_slot_tx], dB_fixed(prach_power), ue->prach_vars[gNB_id]->amp); if (ue->mac_enabled == 1) - nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); + nr_Msg1_transmitted(mod_id, ue->CC_id, frame_tx, gNB_id); - LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n", - ue->Mod_id, - frame_tx, - nr_tti_tx, - gNB_id, - prach_resources->ra_PreambleIndex, - ue->tx_power_dBm[nr_tti_tx], - pathloss); - - LOG_D(PHY,"[UE %d] frame %d nr_tti_tx %d : prach_cnt %d\n", ue->Mod_id, frame_tx, nr_tti_tx, ue->prach_cnt); - - ue->prach_cnt++; - - if (ue->prach_cnt == 3) - ue->prach_cnt = 0; } else if (nr_prach == 2) { - nr_ra_succeeded(mod_id, ue->CC_id, gNB_id); + + LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id); + + ue->UE_mode[gNB_id] = PUSCH; + + } else if(nr_prach == 3){ + + LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id); + + ue->UE_mode[gNB_id] = PRACH; + } - // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue - if (runmode == calib_prach_tx) - ue->prach_resources[gNB_id] = NULL; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); + } diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c index b51c8afbb0..f43f4d98c9 100644 --- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c @@ -97,8 +97,8 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, G_b_f_c = 0; } else { - G_b_f_c = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][gNB_id][0]->g_pucch; - LOG_W(PHY,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); + G_b_f_c = ue->dlsch[proc->thread_id][gNB_id][0]->g_pucch; + LOG_D(PHY,"PUCCH Transmit power control command not yet implemented for NR : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (PUCCH_POWER_DEFAULT); } @@ -169,7 +169,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, //int K_PUCCH = 0; if (O_ACK != 0) { /* it assumes that PDCCH is in the first symbol of receive slot FFS TDDO NR */ - //int slots_gap = (proc->nr_tti_tx > proc->nr_tti_rx ? (proc->nr_tti_tx - proc->nr_tti_rx - 1) : ((proc->nr_tti_tx + ue->frame_parms.ttis_per_subframe) - proc->nr_tti_rx - 1)); + //int slots_gap = (proc->nr_slot_tx > proc->nr_slot_rx ? (proc->nr_slot_tx - proc->nr_slot_rx - 1) : ((proc->nr_slot_tx + ue->frame_parms.slots_per_subframe) - proc->nr_slot_rx - 1)); //K_PUCCH = (slots_gap * (ue->frame_parms.symbols_per_tti)) - 1; } else { diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 9ed9cf34f4..edb070f873 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -33,6 +33,7 @@ * **************************************************************************/ +#include "executables/softmodem-common.h" #include "PHY/NR_REFSIG/ss_pbch_nr.h" #include "PHY/defs_nr_UE.h" #include @@ -99,7 +100,7 @@ void nr_generate_pucch0(int32_t **txdataF, NR_DL_FRAME_PARMS *frame_parms, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t mcs, uint8_t nrofSymbols, uint8_t startingSymbolIndex, @@ -110,7 +111,7 @@ void nr_generate_pucch1(int32_t **txdataF, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint16_t startingPRB, @@ -123,7 +124,7 @@ void nr_generate_pucch2(int32_t **txdataF, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, @@ -136,7 +137,7 @@ void nr_generate_pucch3_4(int32_t **txdataF, PUCCH_CONFIG_DEDICATED *pucch_config_dedicated, uint64_t payload, int16_t amp, - int nr_tti_tx, + int nr_slot_tx, uint8_t nrofSymbols, uint8_t startingSymbolIndex, uint8_t nrofPRB, @@ -201,8 +202,6 @@ void nr_generate_pucch3_4(int32_t **txdataF, * *********************************************************************/ -static int bwp_id = 1; - bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq) { uint8_t sr_payload = 0; @@ -210,7 +209,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ uint64_t pucch_payload = 0; uint32_t csi_payload = 0; int frame_tx = proc->frame_tx; - int nr_tti_tx = proc->nr_tti_tx; + int nr_slot_tx = proc->nr_slot_tx; int Mod_id = ue->Mod_id; int CC_id = ue->CC_id; @@ -228,28 +227,29 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ int pucch_resource_indicator = MAX_PUCCH_RESOURCE_INDICATOR; int n_HARQ_ACK; - uint16_t crnti=0x1234; int dmrs_scrambling_id=0,data_scrambling_id=0; - NR_UE_MAC_INST_t *mac = get_mac_inst(0); NR_PUCCH_Resource_t *pucch_resource; - //NR_UE_MAC_INST_t *mac = get_mac_inst(0); + uint16_t crnti = mac->crnti; + NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; /* update current context */ - int subframe_number = (proc->nr_tti_rx)/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe); + int subframe_number = proc->nr_slot_rx / ue->frame_parms.slots_per_subframe; nb_pucch_format_4_in_subframes[subframe_number] = 0; /* reset pucch format 4 counter at current rx position */ - int dl_harq_pid = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid; + int dl_harq_pid = ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid; - if (dl_harq_pid < ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->number_harq_processes_for_pdsch) { + if (dl_harq_pid < ue->dlsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pdsch) { /* pucch indicator can be reseted in function get_downlink_ack so it should be get now */ - pucch_resource_indicator = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack.pucch_resource_indicator; + pucch_resource_indicator = ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack.pucch_resource_indicator; } + LOG_D(PHY, "PUCCH: %d.%d dl_harq_pid = %d, pucch_resource_indicator = %d\n", frame_tx, nr_slot_tx, dl_harq_pid, pucch_resource_indicator); + /* Part - I - * Collect feedback that should be transmitted at this nr_tti_tx : + * Collect feedback that should be transmitted at this nr_slot_tx : * - ACK/NACK, SR, CSI (CQI, RI, ...) */ @@ -261,11 +261,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, - 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 + CC_id, + frame_tx, + gNB_id, + 0,//ue->pdcch_vars[proc->thread_id][gNB_id]->crnti, + nr_slot_tx); // nr_slot_rx used for meas gap } else { sr_payload = 1; @@ -287,7 +287,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ uint16_t report_slot_csi =csi_MeasConfig->csi_ReportConfigToAddModList->list.array[0]->reportConfigType.choice.periodic->reportSlotConfig.choice.slots320; //if (mac->csirc->reportQuantity.choice.ssb_Index_RSRP){ - if (report_slot_csi == proc->nr_tti_tx) + if (report_slot_csi == proc->nr_slot_tx) csi_status = get_csi_nr(mac, ue, gNB_id, &csi_payload); else csi_status = 0; @@ -301,8 +301,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ if(O_ACK == 0) { N_UCI = O_SR + O_CSI; if ((N_UCI == 0) || ((O_CSI == 0) && (sr_payload == 0))) { /* TS 38.213 9.2.4 UE procedure for reporting SR */ - NR_TST_PHY_PRINTF("PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); - LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); + NR_TST_PHY_PRINTF("PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); + LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); return (FALSE); } else { @@ -354,7 +354,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ int occ_length = 0; int occ_Index = 0; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack; if (select_pucch_resource(ue, mac, gNB_id, N_UCI, pucch_resource_indicator, &initial_pucch_id, &pucch_resource_set, &pucch_resource_id, harq_status) == TRUE) { @@ -389,7 +389,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ if ((ue->UE_mode[gNB_id] != PUSCH) && (O_ACK > 1)) { O_ACK = 1; pucch_ack_payload &= 0x1; /* take only first ack */ - LOG_W(PHY,"PUCCH ue is not expected to generate more than one HARQ-ACK at AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); + LOG_W(PHY,"PUCCH ue is not expected to generate more than one HARQ-ACK at AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); } NR_TST_PHY_PRINTF("PUCCH common configuration with index %d \n", initial_pucch_id); } @@ -442,12 +442,12 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ } } else { - LOG_W(PHY,"PUCCH No PUCCH resource found at AbsSubframe %d.%d \n", frame_tx%1024, nr_tti_tx); + LOG_W(PHY,"PUCCH No PUCCH resource found at AbsSubframe %d.%d \n", frame_tx%1024, nr_slot_tx); return (FALSE); } - int max_code_rate = 0; - int Q_m = BITS_PER_SYMBOL_QPSK; /* default pucch modulation type is QPSK with 2 bits per symbol */ + //int max_code_rate = 0; + //int Q_m = BITS_PER_SYMBOL_QPSK; /* default pucch modulation type is QPSK with 2 bits per symbol */ int N_sc_ctrl_RB = 0; int O_CRC = 0; @@ -476,21 +476,21 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ case pucch_format3_nr: { nb_of_prbs = pucch_resource->format.choice.format3->nrofPRBs; - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->pi2BPSK[0] == 1) { - Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ - } + //if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format3->choice.setup->pi2BPSK[0] == 1) { + // Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ + //} N_sc_ctrl_RB = N_SC_RB; nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping]; break; } case pucch_format4_nr: { - if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->pi2BPSK[0] == 1) { - Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ - } + //if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format4->choice.setup->pi2BPSK[0] == 1) { + // Q_m = BITS_PER_SYMBOL_BPSK; /* set bpsk modulation type with 1 bit per modulation symbol */ + //} nb_symbols = nb_symbols_excluding_dmrs[nb_symbols_total-4][index_additional_dmrs][index_hopping]; nb_of_prbs = 1; - subframe_number = nr_tti_tx/(ue->frame_parms.slots_per_subframe);//ttis_per_subframe); + subframe_number = nr_slot_tx / ue->frame_parms.slots_per_subframe; nb_pucch_format_4_in_subframes[subframe_number]++; /* increment number of transmit pucch 4 in current subframe */ NR_TST_PHY_PRINTF("PUCCH Number of pucch format 4 in subframe %d is %d \n", subframe_number, nb_pucch_format_4_in_subframes[subframe_number]); N_sc_ctrl_RB = N_SC_RB/(nb_pucch_format_4_in_subframes[subframe_number]); @@ -503,7 +503,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ if (format != pucch_format0_nr) { if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1 != NULL) { - max_code_rate = code_rate_r_time_100[mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->maxCodeRate[0]]; /* it is code rate * 10 */ + //max_code_rate = code_rate_r_time_100[mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->maxCodeRate[0]]; /* it is code rate * 10 */ if ((O_ACK != 0) && (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->format1->choice.setup->simultaneousHARQ_ACK_CSI[0] == 0)) { N_UCI = N_UCI - O_CSI; @@ -595,7 +595,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ pucch_payload = pucch_payload | (csi_payload << (O_ACK + O_SR)) | (sr_payload << O_ACK) | pucch_ack_payload; NR_TST_PHY_PRINTF("PUCCH ( AbsSubframe : %d.%d ) ( total payload size %d data 0x%02x ) ( ack length %d data 0x%02x ) ( sr length %d value %d ) ( csi length %d data : 0x%02x ) \n", - frame_tx%1024, nr_tti_tx, N_UCI, pucch_payload, O_ACK, pucch_ack_payload, O_SR, sr_payload, csi_status, csi_payload); + frame_tx%1024, nr_slot_tx, N_UCI, pucch_payload, O_ACK, pucch_ack_payload, O_SR, sr_payload, csi_status, csi_payload); NR_TST_PHY_PRINTF("PUCCH ( format : %d ) ( modulation : %s ) ( nb prb : %d ) ( nb symbols total: %d ) ( nb symbols : %d ) ( max code rate*100 : %d ) ( starting_symbol_index : %d ) \n", format, (Q_m == BITS_PER_SYMBOL_QPSK ? " QPSK " : " BPSK "), nb_of_prbs, nb_symbols_total, nb_symbols, max_code_rate, starting_symbol_index); @@ -612,8 +612,8 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ O_CRC, n_HARQ_ACK); /* set tx power */ - ue->tx_power_dBm[nr_tti_tx] = pucch_tx_power; - ue->tx_total_RE[nr_tti_tx] = nb_of_prbs*N_SC_RB; + ue->tx_power_dBm[nr_slot_tx] = pucch_tx_power; + ue->tx_total_RE[nr_slot_tx] = nb_of_prbs*N_SC_RB; int tx_amp; @@ -635,7 +635,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->pucch_GroupHopping, mac->ULbwp[bwp_id-1]->bwp_Common->pucch_ConfigCommon->choice.setup->hoppingId[0], tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, (uint8_t)m_CS, nb_symbols_total, @@ -650,7 +650,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ &ue->pucch_config_dedicated[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, nb_symbols_total, starting_symbol_index, @@ -671,7 +671,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ &ue->pucch_config_dedicated[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, @@ -683,14 +683,14 @@ 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, - 0,//ue->pdcch_vars[ue->current_thread_id[proc->nr_tti_rx]][gNB_id]->crnti, + 0,//ue->pdcch_vars[proc->thread_id][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, format, &ue->pucch_config_dedicated[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, @@ -743,7 +743,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t int number_harq_feedback = 0; uint32_t dai_current = 0; uint32_t dai_max = 0; - int number_pid_dl = ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->number_harq_processes_for_pdsch; + int number_pid_dl = ue->dlsch[proc->thread_id][gNB_id][0]->number_harq_processes_for_pdsch; bool two_transport_blocks = FALSE; int number_of_code_word = 1; int U_DAI_c = 0; @@ -761,7 +761,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t number_of_code_word = 1; } - if (ue->n_connected_eNB > 1) { + if (ue->n_connected_gNB > 1) { LOG_E(PHY,"PUCCH ACK feedback is not implemented for mutiple gNB cells : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); return (0); } @@ -776,23 +776,19 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t harq_status = &ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]->harq_ack; /* check if current tx slot should transmit downlink acknowlegment */ - if (harq_status->slot_for_feedback_ack == proc->nr_tti_tx) { + if (harq_status->slot_for_feedback_ack == proc->nr_slot_tx) { if (harq_status->ack == DL_ACKNACK_NO_SET) { LOG_E(PHY,"PUCCH Downlink acknowledgment has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return (0); } else if (harq_status->vDAI_DL == DL_DAI_NO_SET) { LOG_E(PHY,"PUCCH Downlink DAI has not been set : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return (0); } else if (harq_status->vDAI_DL > NR_DL_MAX_DAI) { LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return (0); } else if (harq_status->send_harq_status == 0) { - LOG_E(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); - return(0); + LOG_D(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); } else { @@ -808,6 +804,8 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t number_harq_feedback++; ack_data[code_word][dai_current - 1] = harq_status->ack; dai[code_word][dai_current - 1] = dai_current; + harq_status->slot_for_feedback_ack = NR_MAX_SLOTS_PER_FRAME; + harq_status->send_harq_status = 0; } if (do_reset == TRUE) { init_downlink_harq_status(ue->dlsch[thread_idx][gNB_id][code_word]->harq_processes[dl_harq_pid]); @@ -938,6 +936,7 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8 pucch_format_nr_t format_pucch; int ready_pucch_resource_id = FALSE; /* in the case that it is already given */ NR_PUCCH_Resource_t *pucch_resource; + NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; /* ini values to unset */ *initial_pucch_id = NB_INITIAL_PUCCH_RESOURCE; @@ -1008,6 +1007,12 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8 if (resource_set_found == TRUE) { if (pucch_resource_indicator < MAX_PUCCH_RESOURCE_INDICATOR) { + // Verify that the value of pucch_resource_indicator is valid + if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.count <= pucch_resource_indicator) + { + LOG_E(PHY, "Value of pucch_resource_indicator is out of bounds! Possibly due to a false DCI. \n"); + return (FALSE); + } /* check if resource indexing by pucch_resource_indicator of this set is compatible */ if ((ready_pucch_resource_id == TRUE) || (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->resourceList.list.array[pucch_resource_indicator][0] != MAX_NB_OF_PUCCH_RESOURCES)) { @@ -1104,7 +1109,9 @@ boolean_t select_pucch_resource(PHY_VARS_NR_UE *ue, NR_UE_MAC_INST_t *mac, uint8 int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size) { int pucch_resource_set_id = 0; - long *pucch_max_pl_bits = NULL; + NR_BWP_Id_t bwp_id = mac->DL_BWP_Id; + + //long *pucch_max_pl_bits = NULL; /* from TS 38.331 field maxPayloadMinus1 -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE @@ -1116,15 +1123,15 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, int uci_size) /* look for the first resource set which supports uci_size number of bits for payload */ while (pucch_resource_set_id < MAX_NB_OF_PUCCH_RESOURCE_SETS) { if (mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id] != NULL) { - pucch_max_pl_bits = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->maxPayloadMinus1; + //pucch_max_pl_bits = mac->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[pucch_resource_set_id]->maxPayloadMinus1; if (uci_size <= 2) { //TBC rrc (((pucch_max_pl_bits != NULL) ? *pucch_max_pl_bits : 1706) + 1)) { - NR_TST_PHY_PRINTF("PUCCH found resource set %d max bits %d\n", pucch_resource_set_id, pucch_max_pl_bits); + //NR_TST_PHY_PRINTF("PUCCH found resource set %d max bits %d\n", pucch_resource_set_id, pucch_max_pl_bits); pucch_resource_set_id = 0; return (pucch_resource_set_id); break; } else { - pucch_resource_set_id = 1; + pucch_resource_set_id = 1; return (pucch_resource_set_id); break; } @@ -1156,7 +1163,7 @@ boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format { pucch_format_nr_t selected_pucch_format; pucch_format_nr_t selected_pucch_format_second; - NR_SetupRelease_PUCCH_FormatConfig_t *identified_format = NULL; + /*NR_SetupRelease_PUCCH_FormatConfig_t *identified_format = NULL; switch (format_pucch) { case pucch_format1_nr: @@ -1181,7 +1188,7 @@ boolean_t check_pucch_format(NR_UE_MAC_INST_t *mac, uint8_t gNB_id, pucch_format default: break; - } + }*/ /* if ((identified_format != NULL) && (identified_format->choice.setup->nrofSlots[0] != 1)) { LOG_E(PHY,"PUCCH not implemented multislots transmission : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME); @@ -1277,8 +1284,8 @@ int trigger_periodic_scheduling_request(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_n return (1); /* period is slot */ } - int16_t N_slot_frame = NR_NUMBER_OF_SUBFRAMES_PER_FRAME * ue->frame_parms.slots_per_subframe;//ttis_per_subframe; - if (((proc->frame_tx * N_slot_frame) + proc->nr_tti_tx - SR_offset)%SR_periodicity == 0) { + int16_t N_slot_frame = ue->frame_parms.slots_per_frame; + if (((proc->frame_tx * N_slot_frame) + proc->nr_slot_tx - SR_offset)%SR_periodicity == 0) { return (1); } else { diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 3215718f8e..5f8269c513 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -4948,7 +4948,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue, break; default: - LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p), ITTI_MSG_NAME (msg_p)); + LOG_E(PHY, "[UE %ld] Received unexpected message %s\n", ITTI_MSG_DESTINATION_INSTANCE (msg_p), ITTI_MSG_NAME (msg_p)); break; } diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h index ff8406b0c1..796a576aed 100644 --- a/openair1/SIMULATION/LTE_PHY/common_sim.h +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -1,8 +1,4 @@ -static int cmpdouble(const void *p1, const void *p2) { - return *(double *)p1 > *(double *)p2; -} - double median(varArray_t *input) { return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 94214ab3b3..667913d377 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -79,6 +79,9 @@ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ double DS_TDL = .03; +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} int emulate_rf = 0; int split73=0; @@ -484,7 +487,7 @@ int n_ch_rlz = 1; int rx_sample_offset = 0; int xforms=0; int dump_table=0; -int loglvl=OAILOG_WARNING; +int loglvl=OAILOG_INFO; int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0; int two_thread_flag=0; int num_rounds = 4;//,fix_rounds=0; @@ -667,7 +670,7 @@ int main(int argc, char **argv) { { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 }, { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, - { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_DEBUG, TYPE_INT, 0 }, + { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_INFO, TYPE_INT, 0 }, { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL, defintval:2, TYPE_INT, 0 }, { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, @@ -902,7 +905,6 @@ int main(int argc, char **argv) { // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt - //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); T_stdout = 1; if (common_flag == 0) { diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c index 2176e272c8..a585e8efc6 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c @@ -689,7 +689,6 @@ int main(int argc, char **argv) // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt - //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); if (common_flag == 0) { switch (N_RB_DL) { diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c index 5073be24f5..b1f4d933b3 100644 --- a/openair1/SIMULATION/LTE_PHY/mbmssim.c +++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c @@ -997,7 +997,6 @@ int main(int argc, char **argv) { // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt - //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); if (common_flag == 0) { switch (N_RB_DL) { diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c index a58f844945..127bfcb533 100644 --- a/openair1/SIMULATION/LTE_PHY/pucchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c @@ -283,7 +283,6 @@ int main(int argc, char **argv) { } logInit(); - //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); g_log->log_component[PHY].level = LOG_DEBUG; g_log->log_component[PHY].flag = LOG_HIGH; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 37ce3a65d6..80beee4bed 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -80,6 +80,9 @@ double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} int split73=0; @@ -345,7 +348,7 @@ int main(int argc, char **argv) { unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - unsigned int tx_lev=0,tx_lev_dB,trials,errs[4]= {0,0,0,0},round_trials[4]= {0,0,0,0}; + unsigned int tx_lev=0,tx_lev_dB,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0}; FILE *bler_fd=NULL; char bler_fname[512]; FILE *time_meas_fd=NULL; @@ -406,7 +409,6 @@ int main(int argc, char **argv) { // enable these lines if you need debug info // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt - // itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); // set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1); // set_glog(LOG_DEBUG,LOG_HIGH); //hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 957495181a..061866b12c 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -52,6 +52,7 @@ PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; +UE_nr_rxtx_proc_t proc; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; double cpuf; @@ -426,7 +427,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_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_processes[harq_pid]->pdsch_pdu.pdsch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &dlsch->harq_process.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; @@ -518,7 +519,7 @@ int main(int argc, char **argv) //if (i<16) // printf("encoder output f[%d] = %d\n",i,dlsch->harq_processes[0]->f[i]); - if (dlsch->harq_processes[0]->f[i] == 0) + if (dlsch->harq_process.f[i] == 0) modulated_input[i] = 1.0; ///sqrt(2); //QPSK else modulated_input[i] = -1.0; ///sqrt(2); @@ -546,7 +547,7 @@ int main(int argc, char **argv) else channel_output_uncoded[i] = 0; - if (channel_output_uncoded[i] != dlsch->harq_processes[harq_pid]->f[i]) + if (channel_output_uncoded[i] != dlsch->harq_process.f[i]) errors_bit_uncoded = errors_bit_uncoded + 1; } @@ -559,7 +560,7 @@ int main(int argc, char **argv) vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_DECODING0, VCD_FUNCTION_IN); - ret = nr_dlsch_decoding(UE, channel_output_fixed, &UE->frame_parms, + ret = nr_dlsch_decoding(UE, &proc, 0, channel_output_fixed, &UE->frame_parms, dlsch0_ue, dlsch0_ue->harq_processes[0], frame, nb_symb_sch, slot,harq_pid, is_crnti, llr8_flag); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index d77d7b70b4..9581038283 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -61,13 +61,14 @@ #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 "PHY/NR_REFSIG/ptrs_nr.h" #include "NR_RRCReconfiguration.h" #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" +#include +#include -unsigned char NB_eNB_INST=0; LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -81,7 +82,6 @@ double cpuf; int sf_ahead=4 ; int sl_ahead=0; uint8_t nfapi_mode = 0; -uint16_t NB_UE_INST = 1; uint64_t downlink_frequency[MAX_NUM_CCs][4]; // dummy functions @@ -125,6 +125,32 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } +int +gtpv1u_create_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){ + return 0; +} + +int +gtpv1u_update_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +){ + return 0; +} + +int +nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +){ + return 0; +} + void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigCommon_t *scc @@ -140,15 +166,67 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char short_padding, unsigned short post_padding){return 0;} +// Dummy function to avoid linking error at compilation of nr-dlsim int is_x2ap_enabled(void) { return 0; } +int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { + return 0; +} + // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; +void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg); +void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg); +/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of + dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */ +int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1; +void nr_dlsim_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot) { + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n"); + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0]; + /* manually set free CCE to 0 */ + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + sched_ctrl->coreset = get_coreset( + sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + sched_ctrl->cce_index = 0; + + sched_ctrl->rbStart = g_rbStart; + sched_ctrl->rbSize = g_rbSize; + sched_ctrl->mcs = g_mcsIndex; + sched_ctrl->time_domain_allocation = 2; + sched_ctrl->mcsTableIdx = g_mcsTableIdx; + /* the simulator assumes the HARQ PID is equal to the slot number */ + sched_ctrl->dl_harq_pid = slot; + /* The scheduler uses lists to track whether a HARQ process is + * free/busy/awaiting retransmission, and updates the HARQ process states. + * However, in the simulation, we never get ack or nack for any HARQ process, + * thus the list and HARQ states don't match what the scheduler expects. + * Therefore, below lines just "repair" everything so that the scheduler + * won't remark that there is no HARQ feedback */ + sched_ctrl->feedback_dl_harq.head = -1; // always overwrite feedback HARQ process + if (sched_ctrl->harq_processes[slot].round == 0) // depending on round set in simulation ... + add_front_nr_list(&sched_ctrl->available_dl_harq, slot); // ... make PID available + else + add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission + sched_ctrl->harq_processes[slot].is_waiting = false; + AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart); + AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize); + AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs); + AssertFatal(sched_ctrl->mcsTableIdx >= 0 && sched_ctrl->mcsTableIdx <= 2, "invalid sched_ctrl->mcsTableIdx %d\n", sched_ctrl->mcsTableIdx); + sched_ctrl->numDmrsCdmGrpsNoData = 1; +} int main(int argc, char **argv) @@ -193,11 +271,10 @@ int main(int argc, char **argv) SCM_t channel_model=AWGN;//Rayleigh1_anticorr; + NB_UE_INST = 1; //double pbch_sinr; //int pbch_tx_ant; int N_RB_DL=106,mu=1; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t dlsch_config; - NR_sched_pucch pucch_sched; //unsigned char frame_type = 0; @@ -219,19 +296,31 @@ int main(int argc, char **argv) int css_flag=0; cpuf = get_cpu_freq_GHz(); + int8_t enable_ptrs = 0; + int8_t modify_dmrs = 0; + int8_t dmrs_arg[2] = {-1,-1};// Invalid values + /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */ + int8_t ptrs_arg[2] = {-1,-1};// Invalid values + + uint16_t ptrsRePerSymb = 0; + uint16_t pdu_bit_map = 0x0; + uint16_t dlPtrsSymPos = 0; + uint16_t ptrsSymbPerSlot = 0; + uint16_t rbSize = 106; + uint8_t mcsIndex = 9; + uint8_t dlsch_threads = 0; if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[NR_DLSIM] Error, configuration module init failed\n"); } randominit(0); - int mcsIndex_set=0,rbStart_set=0,rbSize_set=0; int print_perf = 0; FILE *scg_fd=NULL; - 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:m:w")) != -1) { + 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:d:e:m:w:T:U:q")) != -1) { switch (c) { case 'f': scg_fd = fopen(optarg,"r"); @@ -392,18 +481,22 @@ int main(int argc, char **argv) case 'a': - dlsch_config.rbStart = atoi(optarg); - rbStart_set=1; + g_rbStart = atoi(optarg); break; case 'b': - dlsch_config.rbSize = atoi(optarg); - rbSize_set=1; + g_rbSize = atoi(optarg); + break; + case 'd': + dlsch_threads = atoi(optarg); + break; + case 'e': + g_mcsIndex = atoi(optarg); break; - case 'e': - dlsch_config.mcsIndex[0] = atoi(optarg); - mcsIndex_set=1; + case 'q': + g_mcsTableIdx = 1; + get_softmodem_params()->use_256qam_table = 1; break; case 'm': @@ -418,6 +511,20 @@ int main(int argc, char **argv) output_fd = fopen("txdata.dat", "w+"); break; + case 'T': + enable_ptrs=1; + for(i=0; i < atoi(optarg); i++) { + ptrs_arg[i] = atoi(argv[optind++]); + } + break; + + case 'U': + modify_dmrs = 1; + for(i=0; i < atoi(optarg); i++) { + dmrs_arg[i] = atoi(argv[optind++]); + } + 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", @@ -447,22 +554,29 @@ int main(int argc, char **argv) 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"); + printf("-q Use 2nd MCS table (256 QAM table) for PDSCH\n"); printf("-t Acceptable effective throughput (in percentage)\n"); + printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); + printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n"); printf("-P Print DLSCH performances\n"); printf("-w Write txdata to binary file (one frame)\n"); + printf("-d number of dlsch threads, 0: no dlsch parallelization\n"); exit (-1); break; } } - + logInit(); set_glog(loglvl); T_stdout = 1; + /* initialize the sin table */ + InitSinLUT(); get_softmodem_params()->phy_test = 1; if (snr1set==0) snr1 = snr0+10; + init_dlsch_tpool(dlsch_threads); RC.gNB = (PHY_VARS_gNB**) malloc(sizeof(PHY_VARS_gNB *)); @@ -482,6 +596,7 @@ int main(int argc, char **argv) RC.nb_nr_mac_CC[i] = 1; mac_top_init_gNB(); gNB_mac = RC.nrmac[0]; + gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); @@ -545,7 +660,17 @@ int main(int argc, char **argv) n_tx, 0); - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); + /* -U option modify DMRS */ + if(modify_dmrs) { + update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg); + } + /* -T option enable PTRS */ + if(enable_ptrs) { + update_ptrs_config(secondaryCellGroup, &rbSize, &mcsIndex, ptrs_arg); + } + + + //xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup); AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; @@ -555,10 +680,19 @@ int main(int argc, char **argv) rrc_mac_config_req_gNB(0,0,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); phy_init_nr_gNB(gNB,0,0); N_RB_DL = gNB->frame_parms.N_RB_DL; + NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info; + UE_info->num_UEs=1; + // 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 + /* rrc_mac_config_req_gNB() has created one user, so set the scheduling + * parameters from command line in global variables that will be picked up by + * scheduling preprocessor */ + if (g_mcsIndex < 0) g_mcsIndex = 9; + if (g_rbStart < 0) g_rbStart=0; + if (g_rbSize < 0) g_rbSize = N_RB_DL - g_rbStart; double fs,bw; @@ -647,7 +781,6 @@ int main(int argc, char **argv) else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} UE->perfect_ce = 0; - for (i=0;i<10;i++) UE->current_thread_id[i] = 0; if (init_nr_ue_signal(UE, 1, 0) != 0) { @@ -655,6 +788,9 @@ int main(int argc, char **argv) exit(-1); } + if(modify_dmrs) { + update_dmrs_config( NULL,UE,dmrs_arg); + } init_nr_ue_transport(UE,0); nr_gold_pbch(UE); @@ -662,16 +798,16 @@ int main(int argc, char **argv) nr_l2_init_ue(NULL); UE_mac = get_mac_inst(0); - + 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; UE->if_inst->dl_indication = nr_ue_dl_indication; UE->if_inst->ul_indication = dummy_nr_ue_ul_indication; - + UE_mac->if_module = nr_ue_if_module_init(0); - + unsigned int available_bits=0; unsigned char *estimated_output_bit; unsigned char *test_input_bit; @@ -686,11 +822,6 @@ int main(int argc, char **argv) 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 (rbStart_set==0) dlsch_config.rbStart=0; - if (rbSize_set==0) dlsch_config.rbSize=N_RB_DL-dlsch_config.rbStart; //Configure UE rrc.carrier.MIB = (uint8_t*) malloc(4); @@ -714,13 +845,13 @@ int main(int argc, char **argv) scheduled_response.CC_id = 0; scheduled_response.frame = frame; scheduled_response.slot = slot; - + scheduled_response.thread_id = UE_proc.thread_id; nr_ue_phy_config_request(&UE_mac->phy_config); - NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info; //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels; snrRun = 0; + for (SNR = snr0; SNR < snr1; SNR += .2) { varArray_t *table_tx=initVarArray(1000,sizeof(double)); @@ -734,7 +865,7 @@ int main(int argc, char **argv) reset_meas(&gNB->tinput); reset_meas(&gNB->tprep); reset_meas(&gNB->tparity); - reset_meas(&gNB->toutput); + reset_meas(&gNB->toutput); clear_pdsch_stats(gNB); @@ -753,20 +884,20 @@ int main(int argc, char **argv) //multipath_channel(gNB2UE,s_re,s_im,r_re,r_im,frame_length_complex_samples,0); UE->rx_offset=0; - UE_proc.frame_rx = frame; - UE_proc.nr_tti_rx= slot; - UE_proc.subframe_rx = slot; + UE_proc.thread_id = 0; + UE_proc.frame_rx = frame; + UE_proc.nr_slot_rx = slot; dcireq.frame = frame; dcireq.slot = slot; - NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE->current_thread_id[UE_proc.nr_tti_rx]][0][0]; + NR_UE_DLSCH_t *dlsch0 = UE->dlsch[UE_proc.thread_id][0][0]; int harq_pid = slot; NR_DL_UE_HARQ_t *UE_harq_process = dlsch0->harq_processes[harq_pid]; NR_gNB_DLSCH_t *gNB_dlsch = gNB->dlsch[0][0]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_processes[slot]->pdsch_pdu.pdsch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &gNB_dlsch->harq_process.pdsch_pdu.pdsch_pdu_rel15; UE_harq_process->harq_ack.ack = 0; round = 0; @@ -782,21 +913,39 @@ int main(int argc, char **argv) UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round; - UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid; - gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round; + for (int i=0; iUE_info.num_pdcch_cand[0][i] = 0; - if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config); - else nr_schedule_css_dlsch_phytest(0,frame,slot); + if (css_flag == 0) { + nr_schedule_ue_spec(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_tti_req = &gNB_mac->UL_tti_req[0]; + Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[slot]; Sched_INFO.UL_dci_req = NULL; Sched_INFO.TX_req = &gNB_mac->TX_req[0]; nr_schedule_response(&Sched_INFO); - + + /* PTRS values for DLSIM calculations */ + nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[Sched_INFO.CC_id].dl_tti_request_body; + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[1]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + pdu_bit_map = pdsch_pdu_rel15->pduBitmap; + if(pdu_bit_map & 0x1) { + set_ptrs_symb_idx(&dlPtrsSymPos, + pdsch_pdu_rel15->NrOfSymbols, + pdsch_pdu_rel15->StartSymbolIndex, + 1<PTRSTimeDensity, + pdsch_pdu_rel15->dlDmrsSymbPos); + ptrsSymbPerSlot = get_ptrs_symbols_in_slot(dlPtrsSymPos, pdsch_pdu_rel15->StartSymbolIndex, pdsch_pdu_rel15->NrOfSymbols); + ptrsRePerSymb = ((rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity); + printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb ); + } if (run_initial_sync) nr_common_signal_procedures(gNB,frame,slot); else @@ -811,7 +960,7 @@ int main(int argc, char **argv) } int tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); if (n_trials==1) printf("tx_offset %d, txdataF_offset %d \n", tx_offset,txdataF_offset); - + //TODO: loop over slots for (aa=0; aaframe_parms.nb_antennas_tx; aa++) { @@ -822,38 +971,11 @@ int main(int argc, char **argv) 12, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); - } else {/* + } else { nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], &txdata[aa][tx_offset], 14, frame_parms); - */ - PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], - (int*)&txdata[aa][tx_offset], - frame_parms->ofdm_symbol_size, - 1, - frame_parms->nb_prefix_samples0, - CYCLIC_PREFIX); - - apply_nr_rotation(frame_parms, - (int16_t*)&txdata[aa][tx_offset], - slot, - 0, - 1, - frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0); - PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset+frame_parms->ofdm_symbol_size], - (int*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, - 13, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - apply_nr_rotation(frame_parms, - (int16_t*)&txdata[aa][tx_offset+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size], - slot, - 1, - 13, - frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples); - } } @@ -880,7 +1002,7 @@ int main(int argc, char **argv) r_im[aa][i] = ((double)(((short *)txdata[aa]))[(i<<1)+1]); } } - + double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); //AWGN sigma2_dB = 10 * log10((double)txlev * ((double)UE->frame_parms.ofdm_symbol_size/(12*rel15->rbSize))) - SNR; sigma2 = pow(10, sigma2_dB/10); @@ -893,45 +1015,54 @@ int main(int argc, char **argv) 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))); + /* Add phase noise if enabled */ + if (pdu_bit_map & 0x1) { + phase_noise(ts, &((short*) UE->common_vars.rxdata[aa])[2*i], + &((short*) UE->common_vars.rxdata[aa])[2*i+1]); + } } } - + 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, - normal_txrx); + dlsch_threads); //printf("dlsim round %d ends\n",round); round++; } // round - + //---------------------------------------------------------- //---------------------- count errors ---------------------- //---------------------------------------------------------- - - 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) + + if (UE->dlsch[UE_proc.thread_id][0][0]->last_iteration_cnt >= + UE->dlsch[UE_proc.thread_id][0][0]->max_ldpc_iterations+1) n_errors++; - - NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]]; + + NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars[UE_proc.thread_id]; int16_t *UE_llr = pdsch_vars[0]->llr[0]; - + TBS = UE_harq_process->TBS;//rel15->TBSize[0]; - uint16_t length_dmrs = 1; + uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); 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); + if(pdu_bit_map & 0x1) { + available_bits-= (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2); + printf("[DLSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5u \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb *rel15->nrOfLayers* 2) ); + } 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(((gNB_dlsch->harq_process.f[i] == 0) && (UE_llr[i] <= 0)) || + ((gNB_dlsch->harq_process.f[i] == 1) && (UE_llr[i] >= 0))) { if(errors_scrambling == 0) { LOG_D(PHY,"\n"); @@ -942,9 +1073,9 @@ int main(int argc, char **argv) } 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 + test_input_bit[i] = (gNB_dlsch->harq_process.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) @@ -978,15 +1109,15 @@ int main(int argc, char **argv) printf("*****************************************\n"); printf("\n"); dump_pdsch_stats(gNB); - printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS); + printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS); printf("\n"); 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)); + 1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex, + gNB->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3, + gNB->dlsch[0][0]->harq_process.K, + gNB->dlsch[0][0]->harq_process.K/((gNB->dlsch[0][0]->harq_process.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"); @@ -1015,9 +1146,9 @@ int main(int argc, char **argv) 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[UE_proc.thread_id][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE_proc.thread_id][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE_proc.thread_id][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), @@ -1039,12 +1170,12 @@ int main(int argc, char **argv) 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); - LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]][0]->llr[0],available_bits,1,0); + LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE_proc.thread_id][0]->llr[0],available_bits,1,0); break; } //if ((float)n_errors/(float)n_trials <= target_error_rate) { - if (effRate >= (eff_tp_check*TBS)) { + if (effRate > (eff_tp_check*TBS)) { printf("PDSCH test OK\n"); break; } @@ -1088,3 +1219,79 @@ int main(int argc, char **argv) return(n_errors); } + + +void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex, int8_t *ptrs_arg) +{ + NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0]; + int *ptrsFreqDenst = calloc(2, sizeof(long)); + ptrsFreqDenst[0]= 25; + ptrsFreqDenst[1]= 115; + int *ptrsTimeDenst = calloc(3, sizeof(long)); + ptrsTimeDenst[0]= 2; + ptrsTimeDenst[1]= 4; + ptrsTimeDenst[2]= 10; + + int epre_Ratio = 0; + int reOffset = 0; + + if(ptrs_arg[0] ==0) { + ptrsTimeDenst[2]= *mcsIndex -1; + } + else if(ptrs_arg[0] == 1) { + ptrsTimeDenst[1]= *mcsIndex - 1; + ptrsTimeDenst[2]= *mcsIndex + 1; + } + else if(ptrs_arg[0] ==2) { + ptrsTimeDenst[0]= *mcsIndex - 1; + ptrsTimeDenst[1]= *mcsIndex + 1; + } + else { + printf("[DLSIM] Wrong L_PTRS value, using default values 1\n"); + } + /* L = 4 if Imcs < MCS4 */ + if(ptrs_arg[1] ==2) { + ptrsFreqDenst[0]= *rbSize - 1; + ptrsFreqDenst[1]= *rbSize + 1; + } + else if(ptrs_arg[1] == 4) { + ptrsFreqDenst[1]= *rbSize - 1; + } + else { + printf("[DLSIM] Wrong K_PTRS value, using default values 2\n"); + } + printf("[DLSIM] PTRS Enabled with L %d, K %d \n", 1<= 0 && dmrs_arg[1] <3 ) { + add_pos = dmrs_arg[1]; + } + + if(scg != NULL) { + NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0]; + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = add_pos; + for (int i=0;ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) { + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type; + } + } + if(ue != NULL) { + for (int i=0;iPDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = mapping_type; + } + ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = add_pos; + } + printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d \n", dmrs_arg[0], dmrs_arg[1] ); +} diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index c7ee863c35..2673ca0524 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -7,3 +7,15 @@ int32_t get_uldl_offset(int nr_bandP) { re NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } +void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, + fapi_nr_dci_indication_t *dci_ind, + fapi_nr_rx_indication_t *rx_ind, + UE_nr_rxtx_proc_t *proc, + PHY_VARS_NR_UE *ue, + uint8_t gNB_id) {} +void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, + uint8_t pdu_type, + uint8_t gNB_id, + PHY_VARS_NR_UE *ue, + NR_UE_DLSCH_t *dlsch0, + uint16_t n_pdus) {} diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c index bfb9150868..57b540f699 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c @@ -83,7 +83,6 @@ void nr_get_prach_resources(module_id_t mod_id, int CC_id, uint8_t gNB_id, uint8_t t_id, - uint8_t first_Msg3, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ @@ -206,9 +205,6 @@ void nr_get_prach_resources(module_id_t mod_id, AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); } - // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 - mac->deltaPreamble_Msg3 = 0; - deltaPreamble_Msg3 = mac->deltaPreamble_Msg3; } PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index 7a465e0ea3..a7150fb2f9 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -235,8 +235,8 @@ void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap); void prepare_scc(NR_ServingCellConfigCommon_t *scc); -s1ap_eNB_config_t s1ap_config; -uint32_t s1ap_generate_eNB_id(void) {return 0;} +ngap_gNB_config_t ngap_config; +uint32_t ngap_generate_gNB_id(void) {return 0;} void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;} void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;} diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 833b81f853..2ff89364d3 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -35,6 +35,7 @@ #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" +#include "PHY/MODULATION/nr_modulation.h" #include "PHY/INIT/phy_init.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" @@ -45,6 +46,7 @@ #include "openair1/SIMULATION/RF/rf.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" +#include "openair1/PHY/MODULATION/nr_modulation.h" //#define DEBUG_NR_PBCHSIM @@ -673,11 +675,12 @@ int main(int argc, char **argv) } if (UE->is_synchronized == 0) { UE_nr_rxtx_proc_t proc={0}; - ret = nr_initial_sync(&proc, UE, normal_txrx,1); + ret = nr_initial_sync(&proc, UE, 1); printf("nr_initial_sync1 returns %d\n",ret); if (ret<0) n_errors++; } else { + UE_nr_rxtx_proc_t proc={0}; UE->rx_offset=0; uint8_t ssb_index = 0; while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb @@ -686,16 +689,16 @@ int main(int argc, char **argv) int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame); for (int i=UE->symbol_offset+1; isymbol_offset+4; i++) { - nr_slot_fep(UE, - i%frame_parms->symbols_per_slot, - ssb_slot, - 0, - 0); + nr_slot_fep(UE, + &proc, + i%frame_parms->symbols_per_slot, + ssb_slot, + 0, + 0); - nr_pbch_channel_estimation(UE,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); + nr_pbch_channel_estimation(UE,&proc,0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); } - UE_nr_rxtx_proc_t proc={0}; ret = nr_rx_pbch(UE, &proc, diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index dd78524ae1..941a06128f 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -45,11 +45,13 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "nr_unitary_defs.h" #include "OCG_vars.h" +#include +#include + #define NR_PRACH_DEBUG 1 #define PRACH_WRITE_OUTPUT_DEBUG 1 -unsigned char NB_eNB_INST=0; LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -59,7 +61,6 @@ RAN_CONTEXT_t RC; RU_t *ru; double cpuf; extern uint16_t prach_root_sequence_map0_3[838]; -uint16_t NB_UE_INST=1; openair0_config_t openair0_cfg[MAX_CARDS]; uint8_t nfapi_mode=0; int sl_ahead = 0; @@ -98,13 +99,44 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } +int +gtpv1u_create_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){ + return 0; +} + +int +gtpv1u_update_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +){ + return 0; +} + +int +nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +){ + return 0; +} + 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;} +// Dummy function to avoid linking error at compilation of nr-prachsim int is_x2ap_enabled(void) { return 0; } +int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { + return 0; +} + int main(int argc, char **argv){ char c; @@ -114,11 +146,16 @@ int main(int argc, char **argv){ int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0; - uint8_t frame = 1, subframe = 9, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, num_root_sequences = 16, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; + uint8_t frame = 1, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1; - uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB; - uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000; + uint32_t tx_lev = 10000, prach_errors = 0; //,tx_lev_dB; + uint64_t SSB_positions = 0x01; + uint16_t RA_sfn_index; + uint8_t N_RA_slot; + uint8_t config_period; + int prachOccasion = 0; double DS_TDL = .03; + NB_UE_INST=1; // int8_t interf1=-19,interf2=-19; // uint8_t abstraction_flag=0,calibration_flag=0; @@ -146,7 +183,7 @@ int main(int argc, char **argv){ randominit(0); - while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { + while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { switch (c) { case 'a': printf("Running AWGN simulation\n"); @@ -236,6 +273,10 @@ int main(int argc, char **argv){ threequarter_fs=1; break; + case 'm': + mu = atoi(optarg); + break; + case 'n': n_frames = atoi(optarg); break; @@ -363,13 +404,6 @@ int main(int argc, char **argv){ } } - - if (config_index<67) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } - uint16_t N_ZC; - N_ZC = prach_sequence_length == 0 ? 839 : 139; - - printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length); - // Configure log logInit(); set_glog(loglvl); @@ -404,12 +438,20 @@ int main(int argc, char **argv){ frame_parms->N_RB_UL = N_RB_UL; frame_parms->threequarter_fs = threequarter_fs; frame_parms->frame_type = TDD; - frame_parms->freq_range = nr_FR1; + frame_parms->freq_range = (mu==1 ? nr_FR1 : nr_FR2); frame_parms->numerology_index = mu; nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); - //nsymb = (frame_parms->Ncp == 0) ? 14 : 12; + uint64_t absoluteFrequencyPointA = (mu==1 ? 640000 : 2070833); + + uint8_t subframe = slot/frame_parms->slots_per_subframe; + + if (config_index<67 && mu==1) { prach_sequence_length=0; slot = subframe*2; slot_gNB = 1+(subframe*2); } + uint16_t N_ZC = prach_sequence_length == 0 ? 839 : 139; + + printf("Config_index %d, prach_sequence_length %d\n",config_index,prach_sequence_length); + printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Frame type %s, Frequency Range %s\n", NUMBER_OF_OFDM_CARRIERS, @@ -425,7 +467,14 @@ int main(int argc, char **argv){ gNB->gNB_config.carrier_config.num_tx_ant.value = 1; gNB->gNB_config.carrier_config.num_rx_ant.value = 1; - gNB->gNB_config.tdd_table.tdd_period.value = 6; + if (mu==1) + gNB->gNB_config.tdd_table.tdd_period.value = 6; + else if (mu==3) + gNB->gNB_config.tdd_table.tdd_period.value = 3; + else { + printf("unsupported numerology %d\n",mu); + exit(-1); + } gNB->gNB_config.prach_config.num_prach_fd_occasions.value = num_prach_fd_occasions; gNB->gNB_config.prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(nfapi_nr_num_prach_fd_occasions_t)); @@ -433,15 +482,18 @@ int main(int argc, char **argv){ gNB->proc.slot_rx = slot; int ret = get_nr_prach_info_from_index(config_index, - (int)frame, - (int)slot_gNB, - absoluteFrequencyPointA, - mu, - frame_parms->frame_type, - &format, - &start_symbol, - &N_t_slot, - &N_dur); + (int)frame, + (int)slot_gNB, + absoluteFrequencyPointA, + mu, + frame_parms->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur, + &RA_sfn_index, + &N_RA_slot, + &config_period); if (ret == 0) {printf("No prach in %d.%d, mu %d, config_index %d\n",frame,slot,mu,config_index); exit(-1);} format0 = format&0xff; // first column of format from table @@ -450,60 +502,54 @@ int main(int argc, char **argv){ if (format1 != 0xff) { switch(format0) { case 0xa1: - prach_format = 9; + prach_format = 11; break; case 0xa2: - prach_format = 10; + prach_format = 12; break; case 0xa3: - prach_format = 11; + prach_format = 13; break; default: AssertFatal(1==0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); } } else { - switch(format0) { - case 0xa1: - prach_format = 0; - break; - case 0xa2: - prach_format = 1; - break; - case 0xa3: - prach_format = 2; - break; - case 0xb1: - prach_format = 3; - break; - case 0xb2: - prach_format = 4; - break; - case 0xb3: - prach_format = 5; - break; - case 0xb4: - prach_format = 6; - break; - case 0xc0: - prach_format = 7; - break; - case 0xc2: - prach_format = 8; - break; - case 0: - // long formats are handled @ PHY - break; - case 1: - // long formats are handled @ PHY - break; - case 2: - // long formats are handled @ PHY - break; - case 3: - // long formats are handled @ PHY - break; + switch(format0) { // single PRACH format + case 0: + prach_format = 0; + break; + case 1: + prach_format = 1; + break; + case 2: + prach_format = 2; + break; + case 3: + prach_format = 3; + break; + case 0xa1: + prach_format = 4; + break; + case 0xa2: + prach_format = 5; + break; + case 0xa3: + prach_format = 6; + break; + case 0xb1: + prach_format = 7; + break; + case 0xb4: + prach_format = 8; + break; + case 0xc0: + prach_format = 9; + break; + case 0xc2: + prach_format = 10; + break; default: - AssertFatal(1==0, "Invalid PRACH format"); + AssertFatal(1 == 0, "Invalid PRACH format"); } } @@ -623,9 +669,9 @@ int main(int argc, char **argv){ subframe); */ //commented for testing purpose UE_nr_rxtx_proc_t proc={0}; - proc.frame_tx = frame; - proc.nr_tti_tx = slot; - nr_ue_prach_procedures(UE,&proc,0,0); + proc.frame_tx = frame; + proc.nr_slot_tx = slot; + nr_ue_prach_procedures(UE, &proc, 0); /* tx_lev_dB not used later, no need to set */ //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); @@ -701,7 +747,7 @@ int main(int argc, char **argv){ // printf("Sigma2 %f (sigma2_dB %f)\n",sigma2,sigma2_dB); if (awgn_flag == 0) { - multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_tti<<1, 0); + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_frame, 0); } if (n_frames==1) { @@ -726,11 +772,11 @@ int main(int argc, char **argv){ } - rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, slot); + rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot); - gNB->prach_vars.rxsigF = ru->prach_rxsigF; + gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion]; if (n_frames == 1) printf("ncs %d,num_seq %d\n",prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value); - rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay); + rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay); // printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); @@ -748,7 +794,7 @@ int main(int argc, char **argv){ LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1); LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); - LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0], N_ZC, 1, 1); + LOG_M("ru_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1); LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); #endif diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index c14a3d7198..a96a62f656 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -90,7 +90,7 @@ int main(int argc, char **argv) FILE *input_fd=NULL; //uint8_t nacktoack_flag=0; int16_t amp=0x7FFF; - int nr_tti_tx=0; + int nr_slot_tx=0; uint64_t actual_payload=0,payload_received; int nr_bit=1; // maximum value possible is 2 uint8_t m0=0;// higher layer paramater initial cyclic shift @@ -501,13 +501,13 @@ int main(int argc, char **argv) for (trial=0; trialofdm_symbol_size*sizeof(int)); if(format==0){ - nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_tti_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); + nr_generate_pucch0(UE,txdataF,frame_parms,PUCCH_GroupHopping,hopping_id,amp,nr_slot_tx,m0,mcs,nrofSymbols,startingSymbolIndex,startingPRB); } else if (format == 1){ - nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); + nr_generate_pucch1(UE,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,m0,nrofSymbols,startingSymbolIndex,startingPRB,startingPRB_intraSlotHopping,0,nr_bit); } else { - nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_tti_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit); + nr_generate_pucch2(UE,0x1234,dmrs_scrambling_id,data_scrambling_id,txdataF,frame_parms,UE->pucch_config_dedicated,actual_payload,amp,nr_slot_tx,nrofSymbols,startingSymbolIndex,nrofPRB,startingPRB,nr_bit); } int txlev = signal_energy(&txdataF[aa][startingSymbolIndex*frame_parms->ofdm_symbol_size], @@ -536,21 +536,21 @@ int main(int argc, char **argv) if (n_trials==1) printf("rxlev %d (%d dB), sigma2 %f dB, SNR %f, TX %f\n",rxlev,dB_fixed(rxlev),sigma2_dB,SNR,10*log10((double)txlev*UE->frame_parms.ofdm_symbol_size/12)); if(format==0){ - nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; - nfapi_nr_pucch_pdu_t pucch_pdu; - pucch_pdu.subcarrier_spacing = 1; - pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; - pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; - pucch_pdu.bit_len_harq = nr_bit; - pucch_pdu.bit_len_csi_part1 = 0; - pucch_pdu.bit_len_csi_part2 = 0; - pucch_pdu.sr_flag = sr_flag; - pucch_pdu.nr_of_symbols = nrofSymbols; - pucch_pdu.hopping_id = hopping_id; - pucch_pdu.initial_cyclic_shift = 0; - pucch_pdu.start_symbol_index = startingSymbolIndex; - pucch_pdu.prb_start = startingPRB; - nr_decode_pucch0(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu); + nfapi_nr_uci_pucch_pdu_format_0_1_t uci_pdu; + nfapi_nr_pucch_pdu_t pucch_pdu; + pucch_pdu.subcarrier_spacing = 1; + pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; + pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; + pucch_pdu.bit_len_harq = nr_bit; + pucch_pdu.bit_len_csi_part1 = 0; + pucch_pdu.bit_len_csi_part2 = 0; + pucch_pdu.sr_flag = sr_flag; + pucch_pdu.nr_of_symbols = nrofSymbols; + pucch_pdu.hopping_id = hopping_id; + pucch_pdu.initial_cyclic_shift = 0; + pucch_pdu.start_symbol_index = startingSymbolIndex; + pucch_pdu.prb_start = startingPRB; + nr_decode_pucch0(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); if(sr_flag==1){ if (uci_pdu.sr->sr_indication == 0 || uci_pdu.sr->sr_confidence_level == 1) sr_errors+=1; @@ -565,7 +565,7 @@ int main(int argc, char **argv) } else if (format==1) { nr_decode_pucch1(rxdataF,PUCCH_GroupHopping,hopping_id, - &(payload_received),frame_parms,amp,nr_tti_tx, + &(payload_received),frame_parms,amp,nr_slot_tx, m0,nrofSymbols,startingSymbolIndex,startingPRB, startingPRB_intraSlotHopping,timeDomainOCC,nr_bit); if(nr_bit==1) @@ -574,34 +574,34 @@ int main(int argc, char **argv) ack_nack_errors+=((actual_payload^payload_received)&1) + (((actual_payload^payload_received)&2)>>1); } else if (format==2) { - nfapi_nr_uci_pucch_pdu_format_2_3_4_t uci_pdu; - nfapi_nr_pucch_pdu_t pucch_pdu; - pucch_pdu.rnti = 0x1234; - pucch_pdu.subcarrier_spacing = 1; - pucch_pdu.group_hop_flag = PUCCH_GroupHopping&1; - pucch_pdu.sequence_hop_flag = (PUCCH_GroupHopping>>1)&1; - pucch_pdu.bit_len_csi_part1 = nr_bit; - pucch_pdu.bit_len_harq = 0; - pucch_pdu.bit_len_csi_part2 = 0; - pucch_pdu.sr_flag = 0; - pucch_pdu.nr_of_symbols = nrofSymbols; - pucch_pdu.hopping_id = hopping_id; - pucch_pdu.initial_cyclic_shift = 0; - pucch_pdu.start_symbol_index = startingSymbolIndex; - pucch_pdu.prb_size = nrofPRB; - pucch_pdu.prb_start = startingPRB; - pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id; - pucch_pdu.data_scrambling_id = data_scrambling_id; - nr_decode_pucch2(gNB,nr_tti_tx,&uci_pdu,&pucch_pdu); - int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; - if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; - for (int i=0;i>1)&1; + pucch_pdu.bit_len_csi_part1 = nr_bit; + pucch_pdu.bit_len_harq = 0; + pucch_pdu.bit_len_csi_part2 = 0; + pucch_pdu.sr_flag = 0; + pucch_pdu.nr_of_symbols = nrofSymbols; + pucch_pdu.hopping_id = hopping_id; + pucch_pdu.initial_cyclic_shift = 0; + pucch_pdu.start_symbol_index = startingSymbolIndex; + pucch_pdu.prb_size = nrofPRB; + pucch_pdu.prb_start = startingPRB; + pucch_pdu.dmrs_scrambling_id = dmrs_scrambling_id; + pucch_pdu.data_scrambling_id = data_scrambling_id; + nr_decode_pucch2(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); + int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; + if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; + for (int i=0;i>1)+(((actual_payload^payload_received)&4)>>2)+n_errors; diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index f2662d9fe6..afebe4ed97 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -81,7 +81,7 @@ int nr_postDecode_sim(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { if (decodeSuccess) { memcpy(ulsch_harq->b+rdata->offset, ulsch_harq->c[r], - rdata->Kr_bytes- - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)); + rdata->Kr_bytes - (ulsch_harq->F>>3) -((ulsch_harq->C>1)?3:0)); } else { if ( rdata->nbSegments != ulsch_harq->processedSegments ) { int nb=abortTpool(gNB->threadPool, req->key); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index e2a5d23397..fd2e1dc0b7 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -56,13 +56,17 @@ #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/utils/threadPool/thread-pool.h" - +#include "PHY/NR_REFSIG/ptrs_nr.h" #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" +#include +#include + +#include "PHY/NR_REFSIG/ul_ref_seq_nr.h" + //#define DEBUG_ULSIM -unsigned char NB_eNB_INST=0; LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; rlc_info_t Rlc_info_um,Rlc_info_am_config; @@ -75,7 +79,6 @@ int sf_ahead=4 ; int sl_ahead=0; double cpuf; uint8_t nfapi_mode = 0; -uint16_t NB_UE_INST = 1; uint64_t downlink_frequency[MAX_NUM_CCs][4]; @@ -119,11 +122,42 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return 0; } +int +gtpv1u_create_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP){ + return 0; +} + +int +gtpv1u_update_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +){ + return 0; +} + +int +nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +){ + return 0; +} + +// Dummy function to avoid linking error at compilation of nr-ulsim int is_x2ap_enabled(void) { return 0; } +int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { + return 0; +} + // needed for some functions uint16_t n_rnti = 0x1234; openair0_config_t openair0_cfg[MAX_CARDS]; @@ -161,8 +195,8 @@ int main(int argc, char **argv) FILE *input_fd = NULL; SCM_t channel_model = AWGN; //Rayleigh1_anticorr; uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; - double tx_gain=1.0; - double N0=30; + + NB_UE_INST = 1; //unsigned char frame_type = 0; NR_DL_FRAME_PARMS *frame_parms; @@ -176,7 +210,6 @@ int main(int argc, char **argv) int gNB_id = 0; int ap; int tx_offset; - double txlev_float; int32_t txlev; 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) @@ -196,6 +229,13 @@ int main(int argc, char **argv) int ptrs_arg[2] = {-1,-1};// Invalid values /* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */ int dmrs_arg[2] = {-1,-1};// Invalid values + uint16_t ptrsSymPos = 0; + uint16_t ptrsSymbPerSlot = 0; + uint16_t ptrsRePerSymb = 0; + + uint8_t transform_precoding = transform_precoder_disabled; // 0 - ENABLE, 1 - DISABLE + uint8_t num_dmrs_cdm_grps_no_data = 1; + uint8_t mcs_table = 0; UE_nr_rxtx_proc_t UE_proc; FILE *scg_fd=NULL; @@ -214,7 +254,10 @@ int main(int argc, char **argv) //logInit(); randominit(0); - while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) { + /* initialize the sin-cos table */ + InitSinLUT(); + + while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:Z")) != -1) { printf("handling optarg %c\n",c); switch (c) { @@ -447,9 +490,19 @@ int main(int argc, char **argv) params_from_file = 1; break; + case 'Z': + + transform_precoding = transform_precoder_enabled; + num_dmrs_cdm_grps_no_data = 2; + mcs_table = 3; + + printf("NOTE: TRANSFORM PRECODING (SC-FDMA) is ENABLED in UPLINK (0 - ENABLE, 1 - DISABLE) : %d \n", transform_precoding); + + 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("%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 -Z Enable SC-FDMA in Uplink \n", argv[0]); //printf("-d Use TDD\n"); printf("-d Introduce delay in terms of number of samples\n"); printf("-f Number of frames to simulate\n"); @@ -479,6 +532,7 @@ int main(int argc, char **argv) printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n"); printf("-Q If -F used, read parameters from file\n"); + printf("-Z If -Z is used, SC-FDMA or transform precoding is enabled in Uplink \n"); exit(-1); break; @@ -668,20 +722,19 @@ int main(int argc, char **argv) nr_scheduled_response_t scheduled_response; fapi_nr_ul_config_request_t ul_config; fapi_nr_tx_request_t tx_req; - fapi_nr_tx_request_body_t tx_req_body; - + uint8_t ptrs_mcs1 = 2; uint8_t ptrs_mcs2 = 4; uint8_t ptrs_mcs3 = 10; uint16_t n_rb0 = 25; uint16_t n_rb1 = 75; - uint8_t mcs_table = 0; + uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; // | PUSCH_PDU_BITMAP_PUSCH_PTRS; uint8_t max_rounds = 4; uint8_t crc_status = 0; - unsigned char mod_order = nr_get_Qm_ul(Imcs, 0); - uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0); + unsigned char mod_order = nr_get_Qm_ul(Imcs, mcs_table); + uint16_t code_rate = nr_get_code_rate_ul(Imcs, mcs_table); uint8_t mapping_type = typeB; // Default Values pusch_dmrs_type_t dmrs_config_type = pusch_dmrs_type1; // Default Values @@ -711,9 +764,32 @@ int main(int argc, char **argv) uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs); uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch); uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4; + + if (transform_precoding == transform_precoder_enabled) { + + AssertFatal(enable_ptrs == 0, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); + + int8_t index = get_index_for_dmrs_lowpapr_seq((NR_NB_SC_PER_RB/2) * nb_rb); + AssertFatal(index >= 0, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs cannot be multiple of any other primenumber other than 2,3,5\n"); + + dmrs_config_type = pusch_dmrs_type1; + nb_re_dmrs = nb_re_dmrs * num_dmrs_cdm_grps_no_data; + + printf("[ULSIM]: TRANSFORM PRECODING ENABLED. Num RBs: %d, index for DMRS_SEQ: %d\n", nb_rb, index); + } + + unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1); unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers); + + printf("[ULSIM]: length_dmrs: %u, l_prime_mask: %u number_dmrs_symbols: %u, mapping_type: %u add_pos: %d \n", length_dmrs, l_prime_mask, number_dmrs_symbols, mapping_type, add_pos); + printf("[ULSIM]: CDM groups: %u, dmrs_config_type: %d, num_rbs: %u, nb_symb_sch: %u\n", num_dmrs_cdm_grps_no_data, dmrs_config_type, nb_rb, nb_symb_sch); + printf("[ULSIM]: MCS: %d, mod order: %u, code_rate: %u\n", Imcs, mod_order, code_rate); + printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS); + + + uint8_t ulsch_input_buffer[TBS/8]; ulsch_input_buffer[0] = 0x31; @@ -831,7 +907,8 @@ int main(int argc, char **argv) gNB->ulsch[0][0]->harq_processes[harq_pid]->round = round; rv_index = nr_rv_round_map[round]; - UE_proc.nr_tti_tx = slot; + UE_proc.thread_id = 0; + UE_proc.nr_slot_tx = slot; UE_proc.frame_tx = frame; UL_tti_req->SFN = frame; @@ -867,7 +944,7 @@ int main(int argc, char **argv) pusch_pdu->mcs_table = mcs_table; pusch_pdu->target_code_rate = code_rate; pusch_pdu->qam_mod_order = mod_order; - pusch_pdu->transform_precoding = 1; + pusch_pdu->transform_precoding = transform_precoding; pusch_pdu->data_scrambling_id = *scc->physCellId; pusch_pdu->nrOfLayers = 1; pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol; @@ -893,6 +970,13 @@ int main(int argc, char **argv) pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + if (transform_precoding == transform_precoder_enabled) { + + pusch_pdu->dfts_ofdm.low_papr_group_number = *scc->physCellId % 30; // U as defined in 38.211 section 6.4.1.1.1.2 + pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; // V as defined in 38.211 section 6.4.1.1.1.2 + pusch_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + } + // prepare ULSCH/PUSCH reception nr_schedule_response(Sched_INFO); @@ -902,19 +986,19 @@ int main(int argc, char **argv) scheduled_response.CC_id = 0; scheduled_response.frame = frame; scheduled_response.slot = slot; + scheduled_response.thread_id = UE_proc.thread_id; scheduled_response.dl_config = NULL; scheduled_response.ul_config = &ul_config; scheduled_response.tx_request = &tx_req; - scheduled_response.tx_request->tx_request_body = &tx_req_body; - + // Config UL TX PDU tx_req.slot = slot; tx_req.sfn = frame; // tx_req->tx_config // TbD tx_req.number_of_pdus = 1; - tx_req_body.pdu_length = TBS/8; - tx_req_body.pdu_index = 0; - tx_req_body.pdu = &ulsch_input_buffer[0]; + tx_req.tx_request_body[0].pdu_length = TBS/8; + tx_req.tx_request_body[0].pdu_index = 0; + tx_req.tx_request_body[0].pdu = &ulsch_input_buffer[0]; ul_config.slot = slot; ul_config.number_pdus = 1; @@ -944,11 +1028,21 @@ int main(int argc, char **argv) ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + ul_config.ul_config_list[0].pusch_config_pdu.transform_precoding = transform_precoding; + + if (transform_precoding == transform_precoder_enabled) { + + ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_group_number = *scc->physCellId % 30;// U as defined in 38.211 section 6.4.1.1.1.2 + ul_config.ul_config_list[0].pusch_config_pdu.dfts_ofdm.low_papr_sequence_number = 0;// V as defined in 38.211 section 6.4.1.1.1.2 + //ul_config.ul_config_list[0].pusch_config_pdu.pdu_bit_map |= PUSCH_PDU_BITMAP_DFTS_OFDM; + ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + + } + + nr_fill_ulsch(gNB,frame,slot,pusch_pdu); for (int i=0;i<(TBS/8);i++) ulsch_ue[0]->harq_processes[harq_pid]->a[i]=i&0xff; - double scale = 1; - if (input_fd == NULL) { // set FAPI parameters for UE, put them in the scheduled response and call @@ -958,7 +1052,7 @@ int main(int argc, char **argv) /////////////////////////phy_procedures_nr_ue_TX/////////////////////// /////////// - phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, 0); + phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id); if (n_trials==1) { @@ -971,20 +1065,16 @@ int main(int argc, char **argv) txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); - - txlev_float = (double)txlev/scale; // output of signal_energy is fixed point representation - - } else n_trials = 1; if (input_fd == NULL ) { - sigma_dB = N0; + sigma_dB = 10 * log10((double)txlev * ((double)frame_parms->ofdm_symbol_size/(12*nb_rb))) - SNR;; sigma = pow(10,sigma_dB/10); - tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/txlev_float); - if(n_trials==1) printf("txlev_float %f, sigma_dB %f, tx_gain %f tx_offset %d, slot_offset %d\n",10*log10(txlev_float),sigma_dB,tx_gain,tx_offset,slot_offset); + + if(n_trials==1) printf("sigma %f (%f dB), txlev %f (factor %f)\n",sigma,sigma_dB,10*log10((double)txlev),(double)(double)frame_parms->ofdm_symbol_size/(12*nb_rb)); for (i=0; inb_antennas_rx; ap++) { - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((tx_gain*r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point - ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point + ((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); /* Add phase noise if enabled */ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)], @@ -1015,6 +1105,17 @@ int main(int argc, char **argv) } + + if(pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { + set_ptrs_symb_idx(&ptrsSymPos, + pusch_pdu->nr_of_symbols, + pusch_pdu->start_symbol_index, + 1<ul_dmrs_symb_pos); + ptrsSymbPerSlot = get_ptrs_symbols_in_slot(ptrsSymPos, pusch_pdu->start_symbol_index, pusch_pdu->nr_of_symbols); + ptrsRePerSymb = ((pusch_pdu->rb_size + ptrs_freq_density - 1)/ptrs_freq_density); + printf("[ULSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb ); + } //////////////////////////////////////////////////////////// //---------------------------------------------------------- @@ -1079,7 +1180,7 @@ int main(int argc, char **argv) } /* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */ available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density); - printf("After PTRS subtraction available_bits are : %u \n", available_bits); + printf("[ULSIM][PTRS] Available bits are: %5u, removed PTRS bits are: %5d \n",available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * 2) ); } for (i = 0; i < available_bits; i++) { diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c index 1ab935fcae..c88c261667 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/frame_config_test.c @@ -51,16 +51,16 @@ void display_frame_configuration(NR_DL_FRAME_PARMS *frame_parms) { - printf("\nTdd configuration tti %d downlink %d uplink %d period %d \n", frame_parms->ttis_per_subframe, frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots, + printf("\nTdd configuration tti %d downlink %d uplink %d period %d \n", frame_parms->slots_per_subframe, frame_parms->p_tdd_UL_DL_Configuration->nrofDownlinkSlots, frame_parms->p_tdd_UL_DL_Configuration->nrofUplinkSlots, frame_parms->p_tdd_UL_DL_Configuration->dl_UL_TransmissionPeriodicity); int k = (TDD_CONFIG_NB_FRAMES * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) - 1; //19; int tti = 0; - for (int j = 0; j < TDD_CONFIG_NB_FRAMES * frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; j++) { + for (int j = 0; j < TDD_CONFIG_NB_FRAMES * frame_parms->slots_per_frame; j++) { int frame = 0; if (j != 0) { - frame = (frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME)/j; - tti = (j)%(frame_parms->ttis_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME); + frame = j / frame_parms->slots_per_frame; + tti = j % frame_parms->slots_per_frame; } else { frame = 0; @@ -99,9 +99,10 @@ void display_frame_configuration(NR_DL_FRAME_PARMS *frame_parms) { * *********************************************************************/ -void set_tti_test(NR_DL_FRAME_PARMS *frame_parms, int ttis_per_subframe) +void set_tti_test(NR_DL_FRAME_PARMS *frame_parms, int slots_per_subframe) { - frame_parms->ttis_per_subframe = ttis_per_subframe; + frame_parms->slots_per_subframe = slots_per_subframe; + frame_parms->slots_per_frame = slots_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; } /******************************************************************* diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c index fc5360848c..7600dfb08f 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pbch_test.c @@ -94,6 +94,7 @@ extern int pbch_detection(PHY_VARS_NR_UE *ue, runmode_t mode); int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int pss_sequence_number) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); + UE_nr_rxtx_proc_t proc = {0}; int synchro_position; int offset; int16_t *tmp; @@ -130,7 +131,7 @@ int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, in #endif - rx_sss_nr(PHY_vars_UE, &metric_fdd_ncp, &phase_fdd_ncp); + rx_sss_nr(PHY_vars_UE, &proc, &metric_fdd_ncp, &phase_fdd_ncp); #if TEST_SYNCHRO_TIMING_PSS @@ -244,7 +245,7 @@ void set_sequence_sss(PHY_VARS_NR_UE *PHY_vars_UE, int offset, int slot_offset) void insert_sequence_sss(PHY_VARS_NR_UE *PHY_vars_UE, int offset) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_half_frame = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)>>1; + int samples_for_half_frame = frame_parms->samples_per_frame / 2; set_sequence_sss(PHY_vars_UE, offset, 0); @@ -327,7 +328,7 @@ int test_synchro_pss_sss(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, int s int sync_pos2 = synchro_position - frame_parms->nb_prefix_samples; - int sync_pos_slot = (frame_parms->samples_per_tti>>1) - frame_parms->ofdm_symbol_size - frame_parms->nb_prefix_samples; + int sync_pos_slot = (frame_parms->samples_per_slot>>1) - frame_parms->ofdm_symbol_size - frame_parms->nb_prefix_samples; if (sync_pos2 >= sync_pos_slot) PHY_vars_UE->rx_offset = sync_pos2 - sync_pos_slot; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c index fa8b49842f..f3dbc78a73 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.c @@ -300,7 +300,7 @@ typedef enum { void set_random_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int amp) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_frame = (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); + int samples_for_frame = frame_parms->samples_per_frame; int16_t random; int16_t *data_p; random_data_format_t data_format = SINUSOIDAL_DATA; @@ -394,7 +394,7 @@ void set_random_rx_buffer(PHY_VARS_NR_UE *PHY_vars_UE, int amp) { int set_pss_in_rx_buffer_from_external_buffer(PHY_VARS_NR_UE *PHY_vars_UE, short *input_buffer) { NR_DL_FRAME_PARMS *frame_parms = &(PHY_vars_UE->frame_parms); - int samples_for_frame = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe; /* both i and q */ + int samples_for_frame = frame_parms->samples_per_frame; /* both i and q */ for (int aa=0; aaframe_parms.nb_antennas_rx; aa++) { for (int i = 0; i < samples_for_frame; i++) { diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h index 65755b0dfb..f0929e88c0 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pss_util_test.h @@ -69,12 +69,6 @@ typedef struct { int number_of_fail; } test_t; -typedef struct { - uint16_t ofdm_symbol_size; - uint32_t samples_per_tti; - uint32_t samples_per_subframe; -} save_frame_parms_t; - /*************** GLOBAL VARIABLES***********************************/ EXTERN PHY_VARS_eNB *PHY_vars_eNB; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c index ab3ede4b8f..68acea6d98 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_generator_test.c @@ -58,7 +58,7 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { int occ_Index = 0; uint64_t pucch_payload = 0; int tx_amp = 512; - int nr_tti_tx = 0; + int nr_slot_tx = 0; int N_UCI = 0; /* size in bits for Uplink Control Information */ switch(format) { @@ -67,7 +67,7 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { &ue->frame_parms, &ue->pucch_config_dedicated_nr[gNB_id], tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, (uint8_t)m_CS, nb_symbols_total, @@ -82,7 +82,7 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { &ue->pucch_config_dedicated_nr[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, (uint8_t)m_0, nb_symbols_total, starting_symbol_index, @@ -95,13 +95,13 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { case pucch_format2_nr: { nr_generate_pucch2(ue, - ue->pdcch_vars[ue->current_thread_id[nr_tti_tx]][gNB_id]->crnti, + ue->pdcch_vars[thread_number][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, &ue->pucch_config_dedicated_nr[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, @@ -113,14 +113,14 @@ int test_pucch_generators(PHY_VARS_NR_UE *ue) { case pucch_format3_nr: case pucch_format4_nr: { nr_generate_pucch3_4(ue, - ue->pdcch_vars[ue->current_thread_id[nr_tti_tx]][gNB_id]->crnti, + ue->pdcch_vars[thread_number][gNB_id]->crnti, ue->common_vars.txdataF, &ue->frame_parms, format, &ue->pucch_config_dedicated_nr[gNB_id], pucch_payload, tx_amp, - nr_tti_tx, + nr_slot_tx, nb_symbols_total, starting_symbol_index, nb_of_prbs, diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c index ff15dec6a4..f731edc20a 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c @@ -169,7 +169,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("%s", tst_separator); - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; printf("\n => Test : No harq feedback on going\n"); @@ -180,9 +180,9 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr } /* set a tx slot with no ack */ - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; printf("\n => Test : Error due to acknownlegment not set \n"); @@ -232,7 +232,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr v_return = -1; } - ue->n_connected_eNB = 2; + ue->n_connected_gNB = 2; printf("\n => Test : Error due to PUCCH format with multiple cells not already implemented \n"); @@ -240,7 +240,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr v_return = -1; } - ue->n_connected_eNB = 1; + ue->n_connected_gNB = 1; return (v_return); } @@ -267,7 +267,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ common_pucch_configuration(ue, gNB_id, TST_PUCCH_COMMON_CONFIG_INDEX_OK); /* set a tx slot with no ack */ - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; harq_status->ack = DL_ACK; @@ -290,9 +290,9 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ /* set a second ack on a different downlink harq process */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; harq_status->n_CCE = 2; harq_status->N_CCE = 4; @@ -300,7 +300,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ harq_status->send_harq_status = 1; harq_status->vDAI_DL = 2; harq_status->ack = DL_ACK; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; printf("\n => Test : PUCCH format from common config in dedicated mode: two positive downlink ACKnowledgments \n"); @@ -316,7 +316,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ v_return = -1; } - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack.ack = DL_NACK; + ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack.ack = DL_NACK; printf("\n => Test : PUCCH format from common config in dedicated mode: two negative downlink ACKnowledgments \n"); @@ -563,11 +563,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, printf("%s", tst_separator); - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 1; harq_status->ack = DL_ACK; @@ -582,11 +582,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, for (int i = 0; i < TST_NB_STEP_SINGLE_TRANSPORT_BLOCK; i++) { /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; @@ -616,11 +616,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, for (i = 1; i < TST_NB_STEP_SINGLE_TRANSPORT_BLOCK; i = i+2) { /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; @@ -677,14 +677,14 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE for (int code_word = 0; code_word < 2; code_word++) { - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; + ue->dlsch[proc->thread_id][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; @@ -697,7 +697,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE reset_harq = TRUE; } - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; @@ -720,21 +720,21 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE for (int code_word = 0; code_word < 2; code_word++) { - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; + ue->dlsch[proc->thread_id][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; for (int j = 0 ; j < 2; j++) { - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; } @@ -754,21 +754,21 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE for (int code_word = 0; code_word < 2; code_word++) { - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; + ue->dlsch[proc->thread_id][gNB_id][code_word]->Number_MCS_HARQ_DL_DCI = 2; /* set a tx slot with no ack */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; + ue->dlsch[proc->thread_id][gNB_id][code_word]->current_harq_pid = dl_harq_pid[i]; - NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; + NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][code_word]->harq_processes[dl_harq_pid[i]].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = i+1; harq_status->ack = DL_ACK; for (int j = 0 ; j < 2; j++) { - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; } @@ -935,7 +935,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p } /* restore single transport block */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->Number_MCS_HARQ_DL_DCI = 1; + ue->dlsch[proc->thread_id][gNB_id][0]->Number_MCS_HARQ_DL_DCI = 1; return (v_return); } @@ -976,11 +976,11 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro NR_UE_HARQ_STATUS_t *harq_status; - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 1; harq_status->ack = DL_ACK; @@ -1015,11 +1015,11 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro /* set a second harq ack context */ - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_SECOND; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_SECOND].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 2; harq_status->ack = DL_ACK; @@ -1073,7 +1073,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) printf("%s", tst_separator); - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = NR_MAX_DLSCH_HARQ_PROCESSES; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = NR_MAX_DLSCH_HARQ_PROCESSES; set_csi_nr( 4, 0x0E ); @@ -1090,11 +1090,11 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) NR_UE_HARQ_STATUS_t *harq_status; - ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; + ue->dlsch[proc->thread_id][gNB_id][0]->current_harq_pid = TST_DL_HARQ_PID_FIRST; - harq_status = &ue->dlsch[ue->current_thread_id[proc->nr_tti_rx]][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; + harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[TST_DL_HARQ_PID_FIRST].harq_ack; - harq_status->slot_for_feedback_ack = proc->nr_tti_tx; + harq_status->slot_for_feedback_ack = proc->nr_slot_tx; harq_status->send_harq_status = 1; harq_status->vDAI_DL = 1; harq_status->ack = DL_ACK; @@ -1168,9 +1168,11 @@ int test_pucch(PHY_VARS_NR_UE *ue) assert(0); } - proc->frame_tx = 0; - proc->nr_tti_rx = 0; - proc->nr_tti_tx = (proc->nr_tti_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX)%(ue->frame_parms.ttis_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); + proc->frame_rx = 0; + proc->nr_slot_rx = 0; + + proc->frame_tx = proc->frame_rx + (proc->nr_slot_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX) / ue->frame_parms.slots_per_frame; + proc->nr_slot_tx = (proc->nr_slot_rx + NR_UE_CAPABILITY_SLOT_RX_TO_TX) % ue->frame_parms.slots_per_frame; init_pucch_power_configuration( ue, gNB_id); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c index 0bbe7cac7f..aedb5729a3 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/srs_test.c @@ -223,12 +223,12 @@ int test_srs_periodicity(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) } printf("srs period %d offset %d \n", srs_current_period, p_srs_resource->SRS_Offset); - int duration = (10 * srs_current_period)/(NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe); + int duration = (10 * srs_current_period) / frame_parms->slots_per_frame; for (int frame_tx = 0; frame_tx < duration; frame_tx++) { - for (int slot_tx = 0; slot_tx < (NR_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->ttis_per_subframe); slot_tx++) { - proc->frame_tx = frame_tx; - proc->nr_tti_tx = slot_tx; + for (int slot_tx = 0; slot_tx < frame_parms->slots_per_frame; slot_tx++) { + proc->frame_tx = frame_tx; + proc->nr_slot_tx = slot_tx; if (ue_srs_procedure_nr( ue, proc, 0) == 0) { printf("test_srs_periodicity srs at frame %d slot %d \n", frame_tx, slot_tx); } @@ -372,7 +372,7 @@ int test_srs(PHY_VARS_NR_UE *PHY_vars_UE) /* start test of sounding reference signals */ default_srs_configuration(frame_parms); - txptr = calloc(frame_parms->samples_per_tti , sizeof(int32_t)); + txptr = calloc(frame_parms->samples_per_slot , sizeof(int32_t)); if (txptr == NULL) { printf("Error test_srs: memory allocation problem txptr \n"); assert(0); diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c index 81e232794e..34127b604f 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/sss_test.c @@ -84,6 +84,7 @@ int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, NR_DL_FRAME_PARMS *frame_parms_gNB, test_t *test) { + UE_nr_rxtx_proc_t proc = {0}; VOID_PARAMETER test; int synchro_position; int offset; @@ -133,7 +134,7 @@ int test_synchro_pss_sss_nr(PHY_VARS_NR_UE *PHY_vars_UE, int position_symbol, NR #endif - rx_sss_nr(PHY_vars_UE, &metric_fdd_ncp, &phase_fdd_ncp); + rx_sss_nr(PHY_vars_UE, &proc, &metric_fdd_ncp, &phase_fdd_ncp); #if TEST_SYNCHRO_TIMING_PSS diff --git a/openair1/SIMULATION/TOOLS/phase_noise.c b/openair1/SIMULATION/TOOLS/phase_noise.c index f243a09c59..5958a0ccdd 100644 --- a/openair1/SIMULATION/TOOLS/phase_noise.c +++ b/openair1/SIMULATION/TOOLS/phase_noise.c @@ -29,14 +29,43 @@ /* linear phase noise model */ void phase_noise(double ts, int16_t * InRe, int16_t * InIm) { + static uint64_t i=0; + int32_t x=0 ,y=0; double fd = 300;//0.01*30000 - static double i=0; - double real, imag,x ,y; + int16_t SinValue = 0, CosValue= 0; + double IdxDouble = (double)(i*fd * ts * ResolSinCos * 4); + int16_t IdxModulo = ((int32_t)(IdxDouble>0 ? IdxDouble+0.5 : IdxDouble-0.5)) % (ResolSinCos*4); + IdxModulo = IdxModulo<0 ? IdxModulo+ResolSinCos*4 : IdxModulo; + + if(IdxModulo<2*ResolSinCos) {//< 2 check for 1st and 2nd + if(IdxModulo < ResolSinCos) {// 1st Quadrant + SinValue = LUTSin[IdxModulo]; + CosValue = LUTSin[ResolSinCos-IdxModulo]; + } + else {// 2nd Quadrant + SinValue = LUTSin[2*ResolSinCos-IdxModulo]; + CosValue = -LUTSin[IdxModulo-ResolSinCos]; + } + } + else {// 3rd and 4th Quadrant + if(IdxModulo < 3*ResolSinCos) {// 3rd Quadrant + SinValue = -LUTSin[IdxModulo-2*ResolSinCos]; + CosValue = -LUTSin[3*ResolSinCos-IdxModulo]; + } + else {//4th Quadrant + SinValue = -LUTSin[4*ResolSinCos-IdxModulo]; + CosValue = LUTSin[IdxModulo-3*ResolSinCos]; + } + } + x = ( ((int32_t)InRe[0] * CosValue) - ((int32_t)InIm[0] * SinValue )); + y = ( ((int32_t)InIm[0] * CosValue) + ((int32_t)InRe[0] * SinValue )); + InRe[0]= (int16_t)(x>>14); + InIm[0]= (int16_t)(y>>14); i++; - real = cos(fd * 2 * M_PI * i * ts); - imag = sin (fd * 2 * M_PI * i * ts); - x = ((real * (double)InRe[0]) - (imag * (double)InIm[0])) ; - y= ((real * (double)InIm[0]) + (imag * (double)InRe[0])) ; - InRe[0]= (int16_t)(x); - InIm[0]= (int16_t)(y); +} +/* Initialisation function for SIN table values */ +void InitSinLUT( void ) { + for ( int i=0; i<(ResolSinCos+1); i++ ) { + LUTSin[i] = sin((double)(M_PI*i)/(2*ResolSinCos)) * (1<<14); //Format: Q14 + } } diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index d2684b15c1..55a78e9778 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -466,6 +466,10 @@ double N_RB2channel_bandwidth(uint16_t N_RB); \param ts Sampling time \param *Re *Im Real and Imag part of the signal */ +//look-up table for the sine (cosine) function +#define ResolSinCos 100 +uint16_t LUTSin[ResolSinCos+1]; +void InitSinLUT( void ); void phase_noise(double ts, int16_t * InRe, int16_t * InIm); #include "targets/RT/USER/rfsim.h" diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h index 1948f1596a..86103dd911 100644 --- a/openair2/COMMON/gtpv1_u_messages_def.h +++ b/openair2/COMMON/gtpv1_u_messages_def.h @@ -30,3 +30,7 @@ MESSAGE_DEF(GTPV1U_ENB_DATA_FORWARDING_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_dat MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_req_t, Gtpv1uEndMarkerReq) MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd) MESSAGE_DEF(GTPV1U_ENB_S1_REQ, MESSAGE_PRIORITY_MED, Gtpv1uS1Req, gtpv1uS1Req) + +MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_req_t, NRGtpv1uDeleteTunnelReq) +MESSAGE_DEF(GTPV1U_GNB_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, gtpv1u_gnb_delete_tunnel_resp_t, NRGtpv1uDeleteTunnelResp) +MESSAGE_DEF(GTPV1U_GNB_NG_REQ, MESSAGE_PRIORITY_MED, Gtpv1uNGReq, gtpv1uNGReq) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 14b6e7c0b1..8fde343000 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -26,6 +26,7 @@ #define GTPV1U_MAX_BEARERS_PER_UE max_val_LTE_DRB_Identity +#define NR_GTPV1U_MAX_BEARERS_PER_UE max_val_NR_DRB_Identity #define GTPV1U_ENB_UPDATE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelReq #define GTPV1U_ENB_UPDATE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelResp @@ -40,6 +41,10 @@ #define GTPV1U_ENB_S1_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uS1Req +#define GTPV1U_GNB_DELETE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelReq +#define GTPV1U_GNB_DELETE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uDeleteTunnelResp +#define GTPV1U_GNB_NG_REQ(mSGpTR) (mSGpTR)->ittiMsg.gtpv1uNGReq + #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF typedef struct gtpv1u_enb_create_x2u_tunnel_req_s { @@ -172,4 +177,37 @@ typedef struct { tcp_udp_port_t enb_port_for_S1u_S12_S4_up; } Gtpv1uS1Req; +typedef struct { + in_addr_t gnb_ip_address_for_NGu_up; + tcp_udp_port_t gnb_port_for_NGu_up; +} Gtpv1uNGReq; +typedef struct gtpv1u_gnb_create_tunnel_req_s { + rnti_t rnti; + int num_tunnels; + teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier + pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; + transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE]; +} gtpv1u_gnb_create_tunnel_req_t; + +typedef struct gtpv1u_gnb_create_tunnel_resp_s { + uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0) + rnti_t rnti; + int num_tunnels; + teid_t gnb_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier + pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; + transport_layer_addr_t gnb_addr; +} gtpv1u_gnb_create_tunnel_resp_t; + +typedef struct gtpv1u_gnb_delete_tunnel_req_s { + rnti_t rnti; + uint8_t num_pdusession; + pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; +} gtpv1u_gnb_delete_tunnel_req_t; + +typedef struct gtpv1u_gnb_delete_tunnel_resp_s { + rnti_t rnti; + uint8_t status; ///< Status of NGU endpoint deleteion (Failed = 0xFF or Success = 0x0) + teid_t gnb_NGu_teid; ///< local NGU Tunnel Endpoint Identifier to be deleted +} gtpv1u_gnb_delete_tunnel_resp_t; + #endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/itti_sim_messages_def.h b/openair2/COMMON/itti_sim_messages_def.h new file mode 100644 index 0000000000..681fc932dd --- /dev/null +++ b/openair2/COMMON/itti_sim_messages_def.h @@ -0,0 +1,36 @@ +/* + * 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 itti_sim_messages_def.h + * \brief itti message for itti simulator + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + + +MESSAGE_DEF(GNB_RRC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBBCCHind) +MESSAGE_DEF(GNB_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBCCCHind) +MESSAGE_DEF(GNB_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBDCCHind) +MESSAGE_DEF(UE_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UECCCHind) +MESSAGE_DEF(UE_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UEDCCHind) diff --git a/openair2/COMMON/itti_sim_messages_types.h b/openair2/COMMON/itti_sim_messages_types.h new file mode 100644 index 0000000000..2e29e8f508 --- /dev/null +++ b/openair2/COMMON/itti_sim_messages_types.h @@ -0,0 +1,51 @@ +/* + * 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 itti_sim_messages_types.h + * \brief itti message for itti simulator + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + +#ifndef ITTI_SIM_MESSAGES_TYPES_H_ +#define ITTI_SIM_MESSAGES_TYPES_H_ + +#include "LTE_asn_constant.h" + + + +#define GNB_RRC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBBCCHind +#define GNB_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBCCCHind +#define GNB_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBDCCHind +#define UE_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UECCCHind +#define UE_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UEDCCHind + + + +typedef struct itti_sim_rrc_ch_s { + rb_id_t rbid; + uint8_t *sdu; + int size; +} itti_sim_rrc_ch_t; + +#endif /* ITTI_SIM_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h index 09b3f2aab4..eeef0d4494 100644 --- a/openair2/COMMON/mac_messages_def.h +++ b/openair2/COMMON/mac_messages_def.h @@ -41,10 +41,16 @@ MESSAGE_DEF(RRC_MAC_CCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDat MESSAGE_DEF(RRC_MAC_CCCH_DATA_CNF, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataCnf, rrc_mac_ccch_data_cnf) MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDataInd, rrc_mac_ccch_data_ind) + MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataReq, rrc_mac_mcch_data_req) MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind) MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req) /* RRC configures DRX context (MAC timers) of a UE */ -MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req) \ No newline at end of file +MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req) + +// gNB +MESSAGE_DEF(NR_RRC_MAC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacCcchDataInd, nr_rrc_mac_ccch_data_ind) +MESSAGE_DEF(NR_RRC_MAC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcMacBcchDataInd, nr_rrc_mac_bcch_data_ind) + diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index e227296d05..f42813ecb0 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -38,6 +38,7 @@ #define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_req #define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_ind +#define NR_RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_bcch_data_ind #define RRC_MAC_BCCH_MBMS_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_req #define RRC_MAC_BCCH_MBMS_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_ind @@ -45,6 +46,7 @@ #define RRC_MAC_CCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_req #define RRC_MAC_CCCH_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_cnf #define RRC_MAC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_ccch_data_ind +#define NR_RRC_MAC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_ccch_data_ind #define RRC_MAC_MCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_req #define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind @@ -86,6 +88,15 @@ typedef struct RrcMacBcchDataInd_s { uint8_t rsrp; } RrcMacBcchDataInd; +typedef struct NRRrcMacBcchDataInd_s { + uint32_t frame; + uint8_t sub_frame; + uint32_t sdu_size; + uint8_t sdu[BCCH_SDU_SIZE]; + uint8_t gnb_index; + uint8_t rsrq; + uint8_t rsrp; +} NRRrcMacBcchDataInd; typedef struct RrcMacBcchMbmsDataReq_s { uint32_t frame; @@ -126,6 +137,16 @@ typedef struct RrcMacCcchDataInd_s { int CC_id; } RrcMacCcchDataInd; +typedef struct NRRrcMacCcchDataInd_s { + uint32_t frame; + uint8_t sub_frame; + uint16_t rnti; + uint32_t sdu_size; + uint8_t sdu[CCCH_SDU_SIZE]; + uint8_t gnb_index; + int CC_id; +} NRRrcMacCcchDataInd; + typedef struct RrcMacMcchDataReq_s { uint32_t frame; uint32_t sdu_size; diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h new file mode 100644 index 0000000000..87d8a59fba --- /dev/null +++ b/openair2/COMMON/ngap_messages_def.h @@ -0,0 +1,90 @@ +/* + * 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 + */ + +/* + * ngap_messages_def.h + * + * Created on: 2020 + * Author: Yoshio INOUE, Masayuki HARADA + * Email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +/* Messages for NGAP logging */ +MESSAGE_DEF(NGAP_UPLINK_NAS_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_uplink_nas_log) +MESSAGE_DEF(NGAP_UE_CAPABILITY_IND_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_capability_ind_log) +MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_initial_context_setup_log) +MESSAGE_DEF(NGAP_NAS_NON_DELIVERY_IND_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_nas_non_delivery_ind_log) +MESSAGE_DEF(NGAP_DOWNLINK_NAS_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_downlink_nas_log) +MESSAGE_DEF(NGAP_S1_SETUP_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_s1_setup_log) +MESSAGE_DEF(NGAP_INITIAL_UE_MESSAGE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_initial_ue_message_log) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_REQ_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_req_log) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMMAND_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_command_log) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_complete_log) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_ue_context_release_log) +MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_setup_request_log) +MESSAGE_DEF(NGAP_PDUSESSION_SETUP_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_setup_response_log) +MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_modify_request_log) +MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_modify_response_log) +MESSAGE_DEF(NGAP_PAGING_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_paging_log) +MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_release_request_log) +MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_pdusession_release_response_log) +MESSAGE_DEF(NGAP_ERROR_INDICATION_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_error_indication_log) +MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_path_switch_req_log) +MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_ACK_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , ngap_path_switch_req_ack_log) + +/* gNB application layer -> NGAP messages */ +MESSAGE_DEF(NGAP_REGISTER_GNB_REQ , MESSAGE_PRIORITY_MED, ngap_register_gnb_req_t , ngap_register_gnb_req) + +/* NGAP -> gNB application layer messages */ +MESSAGE_DEF(NGAP_REGISTER_GNB_CNF , MESSAGE_PRIORITY_MED, ngap_register_gnb_cnf_t , ngap_register_gnb_cnf) +MESSAGE_DEF(NGAP_DEREGISTERED_GNB_IND , MESSAGE_PRIORITY_MED, ngap_deregistered_gnb_ind_t , ngap_deregistered_gnb_ind) + +/* RRC -> NGAP messages */ +MESSAGE_DEF(NGAP_NAS_FIRST_REQ , MESSAGE_PRIORITY_MED, ngap_nas_first_req_t , ngap_nas_first_req) +MESSAGE_DEF(NGAP_UPLINK_NAS , MESSAGE_PRIORITY_MED, ngap_uplink_nas_t , ngap_uplink_nas) +MESSAGE_DEF(NGAP_UE_CAPABILITIES_IND , MESSAGE_PRIORITY_MED, ngap_ue_cap_info_ind_t , ngap_ue_cap_info_ind) +MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, ngap_initial_context_setup_resp_t, ngap_initial_context_setup_resp) +MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_FAIL, MESSAGE_PRIORITY_MED, ngap_initial_context_setup_fail_t, ngap_initial_context_setup_fail) +MESSAGE_DEF(NGAP_NAS_NON_DELIVERY_IND , MESSAGE_PRIORITY_MED, ngap_nas_non_delivery_ind_t , ngap_nas_non_delivery_ind) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_RESP , MESSAGE_PRIORITY_MED, ngap_ue_release_resp_t , ngap_ue_release_resp) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, ngap_ue_release_complete_t , ngap_ue_release_complete) +MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_resp_t , ngap_ue_ctxt_modification_resp) +MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_fail_t , ngap_ue_ctxt_modification_fail) +MESSAGE_DEF(NGAP_PDUSESSION_SETUP_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_resp_t , ngap_pdusession_setup_resp) +MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQUEST_FAIL , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_req_fail_t , ngap_pdusession_setup_request_fail) +MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESP , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_resp_t , ngap_pdusession_modify_resp) +MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_pdusession_release_resp_t , ngap_pdusession_release_resp) +MESSAGE_DEF(NGAP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, ngap_path_switch_req_t , ngap_path_switch_req) +MESSAGE_DEF(NGAP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, ngap_path_switch_req_ack_t , ngap_path_switch_req_ack) +MESSAGE_DEF(NGAP_PDUSESSION_MODIFICATION_IND , MESSAGE_PRIORITY_MED, ngap_pdusession_modification_ind_t , ngap_pdusession_modification_ind) + +/* NGAP -> RRC messages */ +MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas ) +MESSAGE_DEF(NGAP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_initial_context_setup_req_t , ngap_initial_context_setup_req ) +MESSAGE_DEF(NGAP_UE_CTXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED, ngap_ue_ctxt_modification_req_t , ngap_ue_ctxt_modification_req) +MESSAGE_DEF(NGAP_PAGING_IND , MESSAGE_PRIORITY_MED, ngap_paging_ind_t , ngap_paging_ind ) +MESSAGE_DEF(NGAP_PDUSESSION_SETUP_REQ , MESSAGE_PRIORITY_MED, ngap_pdusession_setup_req_t , ngap_pdusession_setup_req ) +MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_REQ , MESSAGE_PRIORITY_MED, ngap_pdusession_modify_req_t , ngap_pdusession_modify_req ) +MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_COMMAND , MESSAGE_PRIORITY_MED, ngap_pdusession_release_command_t , ngap_pdusession_release_command) +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, ngap_ue_release_command_t , ngap_ue_release_command) + +/* NGAP <-> RRC messages (can be initiated either by MME or gNB) */ +MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_REQ , MESSAGE_PRIORITY_MED, ngap_ue_release_req_t , ngap_ue_release_req) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h new file mode 100644 index 0000000000..af746b9193 --- /dev/null +++ b/openair2/COMMON/ngap_messages_types.h @@ -0,0 +1,829 @@ +/* + * 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 + */ + +/* + * ngap_messages_types.h + * + * Created on: 2020 + * Author: Yoshio INOUE, Masayuki HARADA + * Email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#ifndef NGAP_MESSAGES_TYPES_H_ +#define NGAP_MESSAGES_TYPES_H_ + +#include "LTE_asn_constant.h" +//-------------------------------------------------------------------------------------------// +// Defines to access message fields. + +#define NGAP_REGISTER_GNB_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_gnb_req + +#define NGAP_REGISTER_GNB_CNF(mSGpTR) (mSGpTR)->ittiMsg.ngap_register_gnb_cnf +#define NGAP_DEREGISTERED_GNB_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_deregistered_gnb_ind + +#define NGAP_NAS_FIRST_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_nas_first_req +#define NGAP_UPLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.ngap_uplink_nas +#define NGAP_UE_CAPABILITIES_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_cap_info_ind +#define NGAP_INITIAL_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_resp +#define NGAP_INITIAL_CONTEXT_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_fail +#define NGAP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_resp +#define NGAP_NAS_NON_DELIVERY_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_nas_non_delivery_ind +#define NGAP_UE_CTXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_resp +#define NGAP_UE_CTXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_fail +#define NGAP_PDUSESSION_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_resp +#define NGAP_PDUSESSION_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_req_fail +#define NGAP_PDUSESSION_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modify_resp +#define NGAP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req +#define NGAP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.ngap_path_switch_req_ack +#define NGAP_PDUSESSION_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modification_ind + +#define NGAP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_nas +#define NGAP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_initial_context_setup_req +#define NGAP_UE_CTXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_ctxt_modification_req +#define NGAP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_command +#define NGAP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_complete +#define NGAP_PDUSESSION_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_setup_req +#define NGAP_PDUSESSION_MODIFY_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_modify_req +#define NGAP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.ngap_paging_ind + +#define NGAP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_req +#define NGAP_PDUSESSION_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_release_command +#define NGAP_PDUSESSION_RELEASE_RESPONSE(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_release_resp + +//-------------------------------------------------------------------------------------------// +/* Maximum number of e-rabs to be setup/deleted in a single message. + * Even if only one bearer will be modified by message. + */ +#define NGAP_MAX_PDUSESSION (LTE_maxDRB + 3) + +/* Length of the transport layer address string + * 160 bits / 8 bits by char. + */ +#define NGAP_TRANSPORT_LAYER_ADDRESS_SIZE (160 / 8) + +#define NGAP_MAX_NB_AMF_IP_ADDRESS 10 +#define NGAP_IMSI_LENGTH 16 + +#define QOSFLOW_MAX_VALUE 64 + +/* Security key length used within gNB + * Even if only 16 bytes will be effectively used, + * the key length is 32 bytes (256 bits) + */ +#define SECURITY_KEY_LENGTH 32 + +typedef enum ngap_paging_drx_e { + NGAP_PAGING_DRX_32 = 0x0, + NGAP_PAGING_DRX_64 = 0x1, + NGAP_PAGING_DRX_128 = 0x2, + NGAP_PAGING_DRX_256 = 0x3 +} ngap_paging_drx_t; + +/* Lower value codepoint + * indicates higher priority. + */ +typedef enum ngap_paging_priority_s { + NGAP_PAGING_PRIO_LEVEL1 = 0, + NGAP_PAGING_PRIO_LEVEL2 = 1, + NGAP_PAGING_PRIO_LEVEL3 = 2, + NGAP_PAGING_PRIO_LEVEL4 = 3, + NGAP_PAGING_PRIO_LEVEL5 = 4, + NGAP_PAGING_PRIO_LEVEL6 = 5, + NGAP_PAGING_PRIO_LEVEL7 = 6, + NGAP_PAGING_PRIO_LEVEL8 = 7 +} ngap_paging_priority_t; + +typedef enum ngap_cn_domain_s { + NGAP_CN_DOMAIN_PS = 1, + NGAP_CN_DOMAIN_CS = 2 +} ngap_cn_domain_t; + +typedef struct ngap_net_ip_address_s { + unsigned ipv4:1; + unsigned ipv6:1; + char ipv4_address[16]; + char ipv6_address[46]; +} ngap_net_ip_address_t; + +typedef uint64_t bitrate_t; + +typedef struct ngap_ambr_s { + bitrate_t br_ul; + bitrate_t br_dl; +} ngap_ambr_t; + +typedef enum ngap_priority_level_s { + NGAP_PRIORITY_LEVEL_SPARE = 0, + NGAP_PRIORITY_LEVEL_HIGHEST = 1, + NGAP_PRIORITY_LEVEL_LOWEST = 14, + NGAP_PRIORITY_LEVEL_NO_PRIORITY = 15 +} ngap_priority_level_t; + +typedef enum ngap_pre_emp_capability_e { + NGAP_PRE_EMPTION_CAPABILITY_ENABLED = 0, + NGAP_PRE_EMPTION_CAPABILITY_DISABLED = 1, + NGAP_PRE_EMPTION_CAPABILITY_MAX, +} ngap_pre_emp_capability_t; + +typedef enum ngap_pre_emp_vulnerability_e { + NGAP_PRE_EMPTION_VULNERABILITY_ENABLED = 0, + NGAP_PRE_EMPTION_VULNERABILITY_DISABLED = 1, + NGAP_PRE_EMPTION_VULNERABILITY_MAX, +} ngap_pre_emp_vulnerability_t; + +typedef struct ngap_allocation_retention_priority_s { + ngap_priority_level_t priority_level; + ngap_pre_emp_capability_t pre_emp_capability; + ngap_pre_emp_vulnerability_t pre_emp_vulnerability; +} ngap_allocation_retention_priority_t; + +typedef struct ngap_security_capabilities_s { + uint16_t nRencryption_algorithms; + uint16_t nRintegrity_algorithms; + uint16_t eUTRAencryption_algorithms; + uint16_t eUTRAintegrity_algorithms; +} ngap_security_capabilities_t; + +/* Provides the establishment cause for the RRC connection request as provided + * by the upper layers. W.r.t. the cause value names: highPriorityAccess + * concerns AC11..AC15, ‘mt Estands for ‘Mobile Terminating Eand ‘mo Efor + * 'Mobile Originating'. Defined in TS 36.331. + */ +typedef enum ngap_rrc_establishment_cause_e { + NGAP_RRC_CAUSE_EMERGENCY = 0x0, + NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS = 0x1, + NGAP_RRC_CAUSE_MT_ACCESS = 0x2, + NGAP_RRC_CAUSE_MO_SIGNALLING = 0x3, + NGAP_RRC_CAUSE_MO_DATA = 0x4, + NGAP_RRC_CAUSE_MO_VOICECALL = 0x5, + NGAP_RRC_CAUSE_MO_VIDEOCALL = 0x6, + NGAP_RRC_CAUSE_MO_SMS = 0x7, + NGAP_RRC_CAUSE_MPS_PRIORITY_ACCESS = 0x8, + NGAP_RRC_CAUSE_MCS_PRIORITY_ACCESS = 0x9, + NGAP_RRC_CAUSE_NOTAVAILABLE = 0x10, + NGAP_RRC_CAUSE_LAST +} ngap_rrc_establishment_cause_t; + +typedef struct ngap_guami_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_len; + uint8_t amf_region_id; + uint16_t amf_set_id; + uint8_t amf_pointer; +} ngap_guami_t; + +typedef struct ngap_allowed_NSSAI_s{ + uint8_t sST; + uint8_t sD_flag; + uint8_t sD[3]; +}ngap_allowed_NSSAI_t; + +typedef struct fiveg_s_tmsi_s { + uint16_t amf_set_id; + uint8_t amf_pointer; + uint32_t m_tmsi; +} fiveg_s_tmsi_t; + +typedef struct ngap_tai_plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; +} ngap_plmn_identity_t; + +typedef struct ngap_ue_paging_identity_s { + fiveg_s_tmsi_t s_tmsi; +} ngap_ue_paging_identity_t; + +typedef enum ngap_ue_identities_presenceMask_e { + NGAP_UE_IDENTITIES_NONE = 0, + NGAP_UE_IDENTITIES_FiveG_s_tmsi = 1 << 1, + NGAP_UE_IDENTITIES_guami = 1 << 2, +} ngap_ue_identities_presenceMask_t; + +typedef struct ngap_ue_identity_s { + ngap_ue_identities_presenceMask_t presenceMask; + fiveg_s_tmsi_t s_tmsi; + ngap_guami_t guami; +} ngap_ue_identity_t; + +typedef struct ngap_nas_pdu_s { + /* Octet string data */ + uint8_t *buffer; + /* Length of the octet string */ + uint32_t length; +} ngap_nas_pdu_t, ngap_ue_radio_cap_t; + +typedef struct ngap_mobility_restriction_s{ + ngap_plmn_identity_t serving_plmn; +}ngap_mobility_restriction_t; + +typedef enum pdu_session_type_e { + PDUSessionType_ipv4 = 0, + PDUSessionType_ipv6 = 1, + PDUSessionType_ipv4v6 = 2, + PDUSessionType_ethernet = 3, + PDUSessionType_unstructured = 4 +}pdu_session_type_t; + +typedef struct ngap_transport_layer_addr_s { + /* Length of the transport layer address buffer in bits. NGAP layer received a + * bit string<1..160> containing one of the following addresses: ipv4, + * ipv6, or ipv4 and ipv6. The layer doesn't interpret the buffer but + * silently forward it to NG-U. + */ + uint8_t pdu_session_type; + uint8_t length; + uint8_t buffer[20]; // in network byte order +} ngap_transport_layer_addr_t; + +#define TRANSPORT_LAYER_ADDR_COPY(dEST,sOURCE) \ + do { \ + AssertFatal(sOURCE.len <= 20); \ + memcpy(dEST.buffer, sOURCE.buffer, sOURCE.len); \ + dEST.length = sOURCE.length; \ + } while (0) + +typedef struct pdusession_level_qos_parameter_s { + uint8_t qfi; + uint64_t fiveQI; + ngap_allocation_retention_priority_t allocation_retention_priority; +} pdusession_level_qos_parameter_t; + +typedef struct pdusession_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + + uint8_t nb_qos; + /* Quality of service for this pdusession */ + pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE]; + /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */ + ngap_nas_pdu_t nas_pdu; + /* The transport layer address for the IP packets */ + ngap_transport_layer_addr_t upf_addr; + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} pdusession_t; + + +typedef enum pdusession_qosflow_mapping_ind_e{ + QOSFLOW_MAPPING_INDICATION_UL = 0, + QOSFLOW_MAPPING_INDICATION_DL = 1, + QOSFLOW_MAPPING_INDICATION_NON = 0xFF +}pdusession_qosflow_mapping_ind_t; + +typedef struct pdusession_associate_qosflow_s{ + uint8_t qfi; + pdusession_qosflow_mapping_ind_t qos_flow_mapping_ind; +}pdusession_associate_qosflow_t; + +typedef struct pdusession_setup_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + + /* The transport layer address for the IP packets */ + ngap_transport_layer_addr_t gNB_addr; + + /* UPF Tunnel endpoint identifier */ + uint32_t gtp_teid; + + /* qos flow list number */ + uint8_t nb_of_qos_flow; + + /* qos flow list(1 ~ 64) */ + pdusession_associate_qosflow_t associated_qos_flows[QOSFLOW_MAX_VALUE]; +} pdusession_setup_t; + +typedef struct pdusession_tobe_added_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + + /* Unique drb_ID for the UE. */ + uint8_t drb_ID; + + /* The transport layer address for the IP packets */ + ngap_transport_layer_addr_t upf_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} pdusession_tobe_added_t; + +typedef struct pdusession_admitted_tobe_added_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + + /* Unique drb_ID for the UE. */ + uint8_t drb_ID; + + /* The transport layer address for the IP packets */ + ngap_transport_layer_addr_t gnb_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} pdusession_admitted_tobe_added_t; + + + +typedef struct pdusession_tobeswitched_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + + /* The transport layer address for the IP packets */ + ngap_transport_layer_addr_t upf_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} pdusession_tobeswitched_t; + +typedef struct pdusession_modify_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; +} pdusession_modify_t; + +typedef enum ngap_Cause_e { + NGAP_CAUSE_NOTHING, /* No components present */ + NGAP_CAUSE_RADIO_NETWORK, + NGAP_CAUSE_TRANSPORT, + NGAP_CAUSE_NAS, + NGAP_CAUSE_PROTOCOL, + NGAP_CAUSE_MISC, + /* Extensions may appear below */ + +} ngap_Cause_t; + +typedef struct pdusession_failed_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + /* Cause of the failure */ + // cause_t cause; + ngap_Cause_t cause; + uint8_t cause_value; +} pdusession_failed_t; + +typedef enum ngap_ue_ctxt_modification_present_s { + NGAP_UE_CONTEXT_MODIFICATION_SECURITY_KEY = (1 << 0), + NGAP_UE_CONTEXT_MODIFICATION_UE_AMBR = (1 << 1), + NGAP_UE_CONTEXT_MODIFICATION_UE_SECU_CAP = (1 << 2), +} ngap_ue_ctxt_modification_present_t; + +typedef enum ngap_paging_ind_present_s { + NGAP_PAGING_IND_PAGING_DRX = (1 << 0), + NGAP_PAGING_IND_PAGING_PRIORITY = (1 << 1), +} ngap_paging_ind_present_t; + +//-------------------------------------------------------------------------------------------// +// gNB application layer -> NGAP messages +typedef struct ngap_register_gnb_req_s { + /* Unique gNB_id to identify the gNB within EPC. + * For macro gNB ids this field should be 20 bits long. + * For home gNB ids this field should be 28 bits long. + */ + uint32_t gNB_id; + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Optional name for the cell + * NOTE: the name can be NULL (i.e no name) and will be cropped to 150 + * characters. + */ + char *gNB_name; + + /* Tracking area code */ + uint32_t tac; + +#define PLMN_LIST_MAX_SIZE 6 + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; + + uint16_t num_nssai[PLMN_LIST_MAX_SIZE]; + ngap_allowed_NSSAI_t s_nssai[PLMN_LIST_MAX_SIZE][8]; + + /* Default Paging DRX of the gNB as defined in TS 38.304 */ + ngap_paging_drx_t default_drx; + + /* The gNB IP address to bind */ + net_ip_address_t gnb_ip_address; + + /* Nb of AMF to connect to */ + uint8_t nb_amf; + /* List of AMF to connect to */ + net_ip_address_t amf_ip_address[NGAP_MAX_NB_AMF_IP_ADDRESS]; + uint8_t broadcast_plmn_num[NGAP_MAX_NB_AMF_IP_ADDRESS]; + uint8_t broadcast_plmn_index[NGAP_MAX_NB_AMF_IP_ADDRESS][PLMN_LIST_MAX_SIZE]; + + /* Number of SCTP streams used for a amf association */ + uint16_t sctp_in_streams; + uint16_t sctp_out_streams; +} ngap_register_gnb_req_t; + +//-------------------------------------------------------------------------------------------// +// NGAP -> gNB application layer messages +typedef struct ngap_register_gnb_cnf_s { + /* Nb of AMF connected */ + uint8_t nb_amf; +} ngap_register_gnb_cnf_t; + +typedef struct ngap_deregistered_gnb_ind_s { + /* Nb of AMF connected */ + uint8_t nb_amf; +} ngap_deregistered_gnb_ind_t; + +//-------------------------------------------------------------------------------------------// +// RRC -> NGAP messages + +/* The NAS First Req is the first message exchanged between RRC and NGAP + * for an UE. + * The rnti uniquely identifies an UE within a cell. Later the gnb_ue_ngap_id + * will be the unique identifier used between RRC and NGAP. + */ +typedef struct ngap_nas_first_req_s { + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + /* the chosen PLMN identity as index, see TS 36.331 6.2.2 RRC Connection + * Setup Complete. This index here is zero-based, unlike the standard! */ + int selected_plmn_identity; + + /* Establishment cause as sent by UE */ + ngap_rrc_establishment_cause_t establishment_cause; + + /* NAS PDU */ + ngap_nas_pdu_t nas_pdu; + + /* If this flag is set NGAP layer is expecting the GUAMI. If = 0, + * the temporary s-tmsi is used. + */ + ngap_ue_identity_t ue_identity; +} ngap_nas_first_req_t; + +typedef struct ngap_uplink_nas_s { + /* Unique UE identifier within an gNB */ + uint32_t gNB_ue_ngap_id; + + /* NAS pdu */ + ngap_nas_pdu_t nas_pdu; +} ngap_uplink_nas_t; + +typedef struct ngap_ue_cap_info_ind_s { + uint32_t gNB_ue_ngap_id; + ngap_ue_radio_cap_t ue_radio_cap; +} ngap_ue_cap_info_ind_t; + +typedef struct ngap_initial_context_setup_resp_s { + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession setup-ed in the list */ + uint8_t nb_of_pdusessions; + /* list of pdusession setup-ed by RRC layers */ + pdusession_setup_t pdusessions[NGAP_MAX_PDUSESSION]; + + /* Number of pdusession failed to be setup in list */ + uint8_t nb_of_pdusessions_failed; + /* list of pdusessions that failed to be setup */ + pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION]; +} ngap_initial_context_setup_resp_t; + +typedef struct ngap_initial_context_setup_fail_s { + uint32_t gNB_ue_ngap_id; + + /* TODO add cause */ +} ngap_initial_context_setup_fail_t, ngap_ue_ctxt_modification_fail_t, ngap_pdusession_setup_req_fail_t; + +typedef struct ngap_nas_non_delivery_ind_s { + uint32_t gNB_ue_ngap_id; + ngap_nas_pdu_t nas_pdu; + /* TODO: add cause */ +} ngap_nas_non_delivery_ind_t; + +typedef struct ngap_ue_ctxt_modification_req_s { + uint32_t gNB_ue_ngap_id; + + /* Bit-mask of possible present parameters */ + ngap_ue_ctxt_modification_present_t present; + + /* Following fields are optionnaly present */ + + /* Security key */ + uint8_t security_key[SECURITY_KEY_LENGTH]; + + /* UE aggregate maximum bitrate */ + ngap_ambr_t ue_ambr; + + /* NR Security capabilities */ + ngap_security_capabilities_t security_capabilities; +} ngap_ue_ctxt_modification_req_t; + +typedef struct ngap_ue_ctxt_modification_resp_s { + uint32_t gNB_ue_ngap_id; +} ngap_ue_ctxt_modification_resp_t; + +typedef struct ngap_ue_release_complete_s { + + uint32_t gNB_ue_ngap_id; + +} ngap_ue_release_complete_t; + +//-------------------------------------------------------------------------------------------// +// NGAP -> RRC messages +typedef struct ngap_downlink_nas_s { + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + /* Unique UE identifier within an gNB */ + uint32_t gNB_ue_ngap_id; + + /* NAS pdu */ + ngap_nas_pdu_t nas_pdu; +} ngap_downlink_nas_t; + + +typedef struct ngap_initial_context_setup_req_s { + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + /* gNB ue ngap id as initialized by NGAP layer */ + uint32_t gNB_ue_ngap_id; + + uint64_t amf_ue_ngap_id:40; + + /* UE aggregate maximum bitrate */ + ngap_ambr_t ue_ambr; + + /* guami */ + ngap_guami_t guami; + + /* allowed nssai */ + uint8_t nb_allowed_nssais; + ngap_allowed_NSSAI_t allowed_nssai[8]; + + /* Security algorithms */ + ngap_security_capabilities_t security_capabilities; + + /* Security key */ + uint8_t security_key[SECURITY_KEY_LENGTH]; + + /* Number of pdusession to be setup in the list */ + uint8_t nb_of_pdusessions; + /* list of pdusession to be setup by RRC layers */ + pdusession_t pdusession_param[NGAP_MAX_PDUSESSION]; + + /* Mobility Restriction List */ + uint8_t mobility_restriction_flag; + ngap_mobility_restriction_t mobility_restriction; + + /* Nas Pdu */ + uint8_t nas_pdu_flag; + ngap_nas_pdu_t nas_pdu; +} ngap_initial_context_setup_req_t; + + +typedef struct ngap_paging_ind_s { + /* UE paging identity */ + ngap_ue_paging_identity_t ue_paging_identity; + + /* Indicates origin of paging */ + ngap_cn_domain_t cn_domain; + + /* PLMN_identity in TAI of Paging*/ + ngap_plmn_identity_t plmn_identity[256]; + + /* TAC in TAIList of Paging*/ + int16_t tac[256]; + + /* size of TAIList*/ + int16_t tai_size; + + /* Optional fields */ + ngap_paging_drx_t paging_drx; + + ngap_paging_priority_t paging_priority; +} ngap_paging_ind_t; + +typedef struct ngap_pdusession_setup_req_s { + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + /* gNB ue ngap id as initialized by NGAP layer */ + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession to be setup in the list */ + uint8_t nb_pdusessions_tosetup; + + /* E RAB setup request */ + pdusession_t pdusession_setup_params[NGAP_MAX_PDUSESSION]; + +} ngap_pdusession_setup_req_t; + +typedef struct ngap_pdusession_setup_resp_s { + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession setup-ed in the list */ + uint8_t nb_of_pdusessions; + /* list of pdusession setup-ed by RRC layers */ + pdusession_setup_t pdusessions[NGAP_MAX_PDUSESSION]; + + /* Number of pdusession failed to be setup in list */ + uint8_t nb_of_pdusessions_failed; + /* list of pdusessions that failed to be setup */ + pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION]; +} ngap_pdusession_setup_resp_t; + +typedef struct ngap_path_switch_req_s { + + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession setup-ed in the list */ + uint8_t nb_of_pdusessions; + + /* list of pdusession setup-ed by RRC layers */ + pdusession_setup_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION]; + + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + ngap_guami_t ue_guami; + + uint16_t ue_initial_id; + + /* Security algorithms */ + ngap_security_capabilities_t security_capabilities; + +} ngap_path_switch_req_t; + +typedef struct ngap_path_switch_req_ack_s { + + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + uint32_t gNB_ue_ngap_id; + + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + /* UE aggregate maximum bitrate */ + ngap_ambr_t ue_ambr; + + /* Number of pdusession setup-ed in the list */ + uint8_t nb_pdusessions_tobeswitched; + + /* list of pdusession to be switched by RRC layers */ + pdusession_tobeswitched_t pdusessions_tobeswitched[NGAP_MAX_PDUSESSION]; + + /* Number of pdusessions to be released by RRC */ + uint8_t nb_pdusessions_tobereleased; + + /* list of pdusessions to be released */ + pdusession_failed_t pdusessions_tobereleased[NGAP_MAX_PDUSESSION]; + + /* Security key */ + int next_hop_chain_count; + uint8_t next_security_key[SECURITY_KEY_LENGTH]; + +} ngap_path_switch_req_ack_t; + +typedef struct ngap_pdusession_modification_ind_s { + + uint32_t gNB_ue_ngap_id; + + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + /* Number of pdusession setup-ed in the list */ + uint8_t nb_of_pdusessions_tobemodified; + + uint8_t nb_of_pdusessions_nottobemodified; + + /* list of pdusession setup-ed by RRC layers */ + pdusession_setup_t pdusessions_tobemodified[NGAP_MAX_PDUSESSION]; + + pdusession_setup_t pdusessions_nottobemodified[NGAP_MAX_PDUSESSION]; + + uint16_t ue_initial_id; + +} ngap_pdusession_modification_ind_t; + +// NGAP --> RRC messages +typedef struct ngap_ue_release_command_s { + + uint32_t gNB_ue_ngap_id; + +} ngap_ue_release_command_t; + + +//-------------------------------------------------------------------------------------------// +// NGAP <-- RRC messages +typedef struct pdusession_release_s { + /* Unique pdusession_id for the UE. */ + uint8_t pdusession_id; + /* Octet string data */ + uint8_t *transfer_buffer; + /* Length of the octet string */ + uint32_t transfer_length; +} pdusession_release_t; + +typedef struct ngap_ue_release_req_s { + uint32_t gNB_ue_ngap_id; + /* Number of pdusession resource in the list */ + uint8_t nb_of_pdusessions; + /* list of pdusession resource by RRC layers */ + pdusession_release_t pdusessions[NGAP_MAX_PDUSESSION]; + ngap_Cause_t cause; + long cause_value; +} ngap_ue_release_req_t, ngap_ue_release_resp_t; + +typedef struct ngap_pdusession_modify_req_s { + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + /* gNB ue ngap id as initialized by NGAP layer */ + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession to be modify in the list */ + uint8_t nb_pdusessions_tomodify; + + /* E RAB modify request */ + pdusession_t pdusession_modify_params[NGAP_MAX_PDUSESSION]; +} ngap_pdusession_modify_req_t; + +typedef struct ngap_pdusession_modify_resp_s { + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession modify-ed in the list */ + uint8_t nb_of_pdusessions; + /* list of pdusession modify-ed by RRC layers */ + pdusession_modify_t pdusessions[NGAP_MAX_PDUSESSION]; + + /* Number of pdusession failed to be modify in list */ + uint8_t nb_of_pdusessions_failed; + /* list of pdusessions that failed to be modify */ + pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION]; +} ngap_pdusession_modify_resp_t; + +typedef struct ngap_pdusession_release_command_s { + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + /* gNB ue ngap id as initialized by NGAP layer */ + uint32_t gNB_ue_ngap_id; + + /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */ + ngap_nas_pdu_t nas_pdu; + + /* Number of pdusession to be released in the list */ + uint8_t nb_pdusessions_torelease; + + /* PDUSession release command */ + pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION]; + +} ngap_pdusession_release_command_t; + +typedef struct ngap_pdusession_release_resp_s { + /* AMF UE id */ + uint64_t amf_ue_ngap_id:40; + + /* gNB ue ngap id as initialized by NGAP layer */ + uint32_t gNB_ue_ngap_id; + + /* Number of pdusession released in the list */ + uint8_t nb_of_pdusessions_released; + + /* list of pdusessions released */ + pdusession_release_t pdusession_release[NGAP_MAX_PDUSESSION]; + + /* Number of pdusession failed to be released in list */ + uint8_t nb_of_pdusessions_failed; + /* list of pdusessions that failed to be released */ + pdusession_failed_t pdusessions_failed[NGAP_MAX_PDUSESSION]; + +} ngap_pdusession_release_resp_t; + +#endif /* NGAP_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/pdcp_messages_def.h b/openair2/COMMON/pdcp_messages_def.h index c4be4b2957..b148ae0e1f 100644 --- a/openair2/COMMON/pdcp_messages_def.h +++ b/openair2/COMMON/pdcp_messages_def.h @@ -31,3 +31,6 @@ MESSAGE_DEF(RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq, rrc_dcch_data_req) MESSAGE_DEF(RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_ind) MESSAGE_DEF(RRC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq, rrc_pcch_data_req) + +// gNB +MESSAGE_DEF(NR_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataInd, nr_rrc_dcch_data_ind) diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index 1551e4283f..daf8ba7cac 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -35,6 +35,9 @@ #define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_ind #define RRC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_pcch_data_req +// gNB +#define NR_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_ind + //-------------------------------------------------------------------------------------------// // Messages between RRC and PDCP layers typedef struct RrcDcchDataReq_s { @@ -61,6 +64,16 @@ typedef struct RrcDcchDataInd_s { uint8_t eNB_index; // LG: needed in UE } RrcDcchDataInd; +typedef struct NRRrcDcchDataInd_s { + uint32_t frame; + uint8_t dcch_index; + uint32_t sdu_size; + uint8_t *sdu_p; + uint16_t rnti; + uint8_t module_id; + uint8_t gNB_index; // LG: needed in UE +} NRRrcDcchDataInd; + typedef struct RrcPcchDataReq_s { uint32_t sdu_size; uint8_t *sdu_p; diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 1cdda40529..70efe7bf4b 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -29,6 +29,7 @@ ***************************************************************************/ #include "LTE_asn_constant.h" +#include "NR_asn_constant.h" #ifndef __PLATFORM_CONSTANTS_H__ # define __PLATFORM_CONSTANTS_H__ @@ -65,18 +66,6 @@ #define MAX_NR_RRC_UE_CONTEXTS 64 #ifndef UE_EXPANSION - // TODO:L2 FAPI simulator. - // UESIM_EXPANSION is used to be same value of MAX_MOBILES_PER_ENB - // in eNB and UE. - // now , if we use --mu option in UE, compiling error will occur. - // This problem will be fixed in the future. - #ifdef UESIM_EXPANSION - #define MAX_MOBILES_PER_ENB 256 - #define MAX_MOBILES_PER_ENB_NB_IoT 256 - #define MAX_MOBILES_PER_GNB 256 - #define MAX_eNB 2 - #define MAX_gNB 2 - #else #ifdef LARGE_SCALE #define MAX_MOBILES_PER_ENB 128 #define MAX_MOBILES_PER_ENB_NB_IoT 128 @@ -90,7 +79,6 @@ #define MAX_eNB 2 #define MAX_gNB 2 #endif - #endif #else #define MAX_MOBILES_PER_ENB 256 #define MAX_MOBILES_PER_ENB_NB_IoT 256 @@ -117,6 +105,7 @@ #define DEFAULT_RAB_ID 1 #define NB_RB_MAX (LTE_maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ +#define NR_NB_RB_MAX (NR_maxDRB + 3) #define NB_RB_MBMS_MAX (LTE_maxSessionPerPMCH*LTE_maxServiceCount) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 2555be081a..d425b9e7d7 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -28,10 +28,13 @@ ***************************************************************************/ #ifndef __PLATFORM_TYPES_H__ -# define __PLATFORM_TYPES_H__ +#define __PLATFORM_TYPES_H__ #if !defined(NAS_NETLINK) - #include +#include +#else +#include +typedef void * intptr_t; #endif //----------------------------------------------------------------------------- @@ -222,16 +225,14 @@ typedef enum config_action_e { //----------------------------------------------------------------------------- typedef uint32_t teid_t; // tunnel endpoint identifier typedef uint8_t ebi_t; // eps bearer id - +typedef uint8_t pdusessionid_t; //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- // may be ITTI not enabled, but type instance is useful also for OTG, -#if !defined(instance_t) - typedef uint16_t instance_t; -#endif +typedef intptr_t instance_t; typedef struct protocol_ctxt_s { module_id_t module_id; /*!< \brief Virtualized module identifier */ eNB_flag_t enb_flag; /*!< \brief Flag to indicate eNB (1) or UE (0) */ @@ -292,13 +293,19 @@ typedef struct protocol_ctxt_s { (Ctxt_Pp)->subframe = sUBfRAME; \ PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp) -#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]" +#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02d][RNTI %" PRIx16 "]" #define PROTOCOL_CTXT_ARGS(CTXT_Pp) \ (CTXT_Pp)->frame, \ ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \ (CTXT_Pp)->module_id, \ (CTXT_Pp)->rnti +#define PROTOCOL_NR_CTXT_ARGS(CTXT_Pp) \ + (CTXT_Pp)->frame, \ + ((CTXT_Pp)->enb_flag == GNB_FLAG_YES) ? "gNB":" UE", \ + (CTXT_Pp)->module_id, \ + (CTXT_Pp)->rnti + #define CHECK_CTXT_ARGS(CTXT_Pp) #define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 6f37c8be1c..02f878ee2e 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -399,8 +399,8 @@ typedef struct NbIoTRrcConfigurationReq_s { // gNB: GNB_APP -> RRC messages typedef struct NRRrcConfigurationReq_s { - uint32_t cell_identity; - uint16_t tac; + uint64_t cell_identity; + uint32_t tac; uint16_t mcc[PLMN_LIST_MAX_SIZE]; uint16_t mnc[PLMN_LIST_MAX_SIZE]; uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index befab4ebdf..f6b4f3c4e2 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -386,6 +386,7 @@ typedef struct s1ap_register_enb_req_s { uint8_t nb_mme; /* List of MME to connect to */ net_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS]; + uint16_t mme_port[S1AP_MAX_NB_MME_IP_ADDRESS]; uint8_t broadcast_plmn_num[S1AP_MAX_NB_MME_IP_ADDRESS]; uint8_t broadcast_plmn_index[S1AP_MAX_NB_MME_IP_ADDRESS][PLMN_LIST_MAX_SIZE]; diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 0fb1bd6b30..33b6d5f9d4 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -74,6 +74,7 @@ TASK_DEF(TASK_PROTO_AGENT, TASK_PRIORITY_MED, 200) /// Radio Resource Control task TASK_DEF(TASK_RRC_UE, TASK_PRIORITY_MED, 200) +TASK_DEF(TASK_RRC_NRUE, TASK_PRIORITY_MED, 200) /// Non Access Stratum task TASK_DEF(TASK_NAS_UE, TASK_PRIORITY_MED, 200) TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200) @@ -81,3 +82,8 @@ TASK_DEF(TASK_RAL_UE, TASK_PRIORITY_MED, 200) //MESSAGE GENERATOR TASK TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200) +#ifdef ITTI_SIM +TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200) +TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200) +#endif + diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index 08ecde26a0..0c55764d6e 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -122,6 +122,8 @@ typedef struct x2ap_register_enb_req_s { * CC Params */ int16_t eutra_band[MAX_NUM_CCs]; + int32_t nr_band[MAX_NUM_CCs]; + int32_t nrARFCN[MAX_NUM_CCs]; uint32_t downlink_frequency[MAX_NUM_CCs]; int32_t uplink_frequency_offset[MAX_NUM_CCs]; uint32_t Nid_cell[MAX_NUM_CCs]; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index f1daacbb65..7ca466e8ff 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -40,6 +40,8 @@ #include "common/utils/LOG/log.h" +#include + /*Array containing the Agent-MAC interfaces*/ AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; @@ -53,10 +55,20 @@ struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *slice_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state slice_config_ringbuffer_state[NUM_MAX_ENB]; +/* Ringbuffer related to slice configuration if we need to wait for additional + * controller information */ +struct lfds700_ringbuffer_element *store_slice_config_array[NUM_MAX_ENB]; +struct lfds700_ringbuffer_state store_slice_config_ringbuffer_state[NUM_MAX_ENB]; +/* stores the (increasing) xid for messages to prevent double use */ +int xid = 50; + /* Ringbuffer-related to slice configuration */ struct lfds700_ringbuffer_element *ue_assoc_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ue_assoc_ringbuffer_state[NUM_MAX_ENB]; +/* a list of shared objects that are loaded into the user plane */ +SLIST_HEAD(flexran_so_handle, flexran_agent_so_handle_s) flexran_handles[NUM_MAX_ENB]; + int flexran_agent_mac_stats_reply_ue(mid_t mod_id, Protocol__FlexUeStatsReport **ue_report, int n_ue, @@ -1363,6 +1375,19 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { &scrng, NULL); + struct lfds700_misc_prng_state sscrng; + i = posix_memalign((void **) &store_slice_config_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, + "posix_memalign(): could not allocate aligned memory\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core( + &store_slice_config_ringbuffer_state[mod_id], + store_slice_config_array[mod_id], + num_elements, + &sscrng, + NULL); + struct lfds700_misc_prng_state uarng; i = posix_memalign((void **) &ue_assoc_array[mod_id], LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, @@ -1382,6 +1407,8 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { RC.mac[mod_id]->UE_info.eNB_UE_stats[UE_PCCID(mod_id,i)][i].harq_pid = 0; } } + + SLIST_INIT(&flexran_handles[mod_id]); } /*********************************************** @@ -1659,6 +1686,8 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) free(dl_mac_config_array[mod_id]); lfds700_ringbuffer_cleanup(&slice_config_ringbuffer_state[mod_id], NULL ); free(slice_config_array[mod_id]); + lfds700_ringbuffer_cleanup(&store_slice_config_ringbuffer_state[mod_id], NULL ); + free(store_slice_config_array[mod_id]); lfds700_ringbuffer_cleanup(&ue_assoc_ringbuffer_state[mod_id], NULL ); free(ue_assoc_array[mod_id]); lfds700_misc_library_cleanup(); @@ -1698,7 +1727,81 @@ void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) { flexran_agent_destroy_mac_slice_config(&helper); } -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) { +int check_scheduler(mid_t mod_id, char *s) { + if (!s) + return 1; + if (dlsym(NULL, s)) + return 1; + flexran_agent_so_handle_t *so = NULL; + SLIST_FOREACH(so, &flexran_handles[mod_id], entries) { + if (strcmp(so->name, s) == 0) + return 1; + } + return 0; +} + +void request_scheduler(mid_t mod_id, char *s, int xid) { + LOG_W(FLEXRAN_AGENT, + "unknown scheduler %s, requesting controller to send it\n", + s); + Protocol__FlexControlDelegationRequest *req = malloc(sizeof(Protocol__FlexControlDelegationRequest)); + DevAssert(req); + protocol__flex_control_delegation_request__init(req); + Protocol__FlexHeader *header = NULL; + int rc = flexran_create_header( + xid, PROTOCOL__FLEX_TYPE__FLPT_DELEGATE_REQUEST, &header); + AssertFatal(rc == 0, "%s(): cannot create header\n", __func__); + req->header = header; + req->delegation_type = PROTOCOL__FLEX_CONTROL_DELEGATION_TYPE__FLCDT_MAC_DL_UE_SCHEDULER; + req->name = strdup(s); + + Protocol__FlexranMessage *msg = malloc(sizeof(Protocol__FlexranMessage)); + DevAssert(msg); + protocol__flexran_message__init(msg); + msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_CONTROL_DEL_REQ_MSG; + msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + msg->control_del_req_msg = req; + + int size = 0; + void *data = flexran_agent_pack_message(msg, &size); + if (flexran_agent_msg_send(mod_id, FLEXRAN_AGENT_DEFAULT, data, size, 0) < 0) + LOG_E(FLEXRAN_AGENT, "%s(): error while sending message\n", __func__); +} + +Protocol__FlexranMessage *request_scheduler_timeout( + mid_t mod_id, + const Protocol__FlexranMessage *msg) { + const Protocol__FlexEnbConfigReply *ecr = msg->enb_config_reply_msg; + + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + + Protocol__FlexranMessage *smsg = NULL; + struct lfds700_ringbuffer_state *state = &store_slice_config_ringbuffer_state[mod_id]; + if (lfds700_ringbuffer_read(state, NULL, (void **) &smsg, &ls)) { + AssertFatal(msg == smsg, + "expected and returned enb_config_reply are not the same\n"); + AssertFatal(ecr->header->xid == smsg->enb_config_reply_msg->header->xid, + "expected and returned enb_config_reply are not the same\n"); + } else { + LOG_E(FLEXRAN_AGENT, "%s(): could not read config from ringbuffer\n", __func__); + } + /* call the helper so that scheduler names are correctly freed */ + helper_destroy_mac_slice_config(ecr->cell_config[0]->slice_config); + ecr->cell_config[0]->slice_config = NULL; + /* we should not call flexran_agent_destroy_enb_config_reply(smsg); since + * upon timer removal, this is automatically done */ + LOG_W(FLEXRAN_AGENT, + "remove stored slice config (xid %d) after timeout\n", + ecr->header->xid); + flexran_agent_destroy_timer(mod_id, ecr->header->xid); + return NULL; +} + +void prepare_update_slice_config(mid_t mod_id, + Protocol__FlexSliceConfig **slice_config, + int request_objects) { if (!*slice_config) return; /* just use the memory and set to NULL in original */ Protocol__FlexSliceConfig *sc = *slice_config; @@ -1709,6 +1812,63 @@ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice lfds700_misc_prng_init(&ls); enum lfds700_misc_flag overwrite_occurred_flag; + int put_on_hold = 0; + if (request_objects + && sc->dl->scheduler + && !check_scheduler(mod_id, sc->dl->scheduler)) { + request_scheduler(mod_id, sc->dl->scheduler, xid++); + put_on_hold = 1; + } + for (int i = 0; request_objects && i < sc->dl->n_slices; ++i) { + Protocol__FlexSlice *sl = sc->dl->slices[i]; + if (sl->scheduler && !check_scheduler(mod_id, sl->scheduler)) { + request_scheduler(mod_id, sl->scheduler, xid++); + put_on_hold = 1; + } + } + if (put_on_hold) { + Protocol__FlexEnbConfigReply *reply = malloc(sizeof(Protocol__FlexEnbConfigReply)); + DevAssert(reply); + protocol__flex_enb_config_reply__init(reply); + /* use the last used xid so we can correlate answer and waiting config */ + int rc = flexran_create_header( + xid - 1, PROTOCOL__FLEX_TYPE__FLPT_GET_ENB_CONFIG_REPLY, &reply->header); + AssertFatal(rc == 0, "%s(): cannot create header\n", __func__); + reply->n_cell_config = 1; + reply->cell_config = malloc(sizeof(Protocol__FlexCellConfig *)); + DevAssert(reply->cell_config); + reply->cell_config[0] = malloc(sizeof(Protocol__FlexCellConfig)); + DevAssert(reply->cell_config[0]); + protocol__flex_cell_config__init(reply->cell_config[0]); + reply->cell_config[0]->slice_config = sc; + + Protocol__FlexranMessage *msg = malloc(sizeof(Protocol__FlexranMessage)); + DevAssert(msg); + protocol__flexran_message__init(msg); + msg->msg_case = PROTOCOL__FLEXRAN_MESSAGE__MSG_ENB_CONFIG_REPLY_MSG; + msg->msg_dir = PROTOCOL__FLEXRAN_DIRECTION__INITIATING_MESSAGE; + msg->enb_config_reply_msg = reply; + + Protocol__FlexEnbConfigReply *o; + lfds700_ringbuffer_write(&store_slice_config_ringbuffer_state[mod_id], + NULL, + (void *)msg, + &overwrite_occurred_flag, + NULL, + (void **) &o, + &ls); + AssertFatal(overwrite_occurred_flag == LFDS700_MISC_FLAG_LOWERED, + "unhandled: stored slice config for controller has been overwritten\n"); + + flexran_agent_create_timer(mod_id, + 3000, + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, + xid - 1, + request_scheduler_timeout, + msg); /* need reply for xid */ + return; + } + Protocol__FlexSliceConfig *overwritten_sc; lfds700_ringbuffer_write(&slice_config_ringbuffer_state[mod_id], NULL, @@ -1756,6 +1916,69 @@ void flexran_agent_slice_update(mid_t mod_id) { apply_update_dl_slice_config(mod_id, sc->dl); apply_update_ul_slice_config(mod_id, sc->ul); helper_destroy_mac_slice_config(sc); + + flexran_agent_so_handle_t *so = NULL; + flexran_agent_so_handle_t *prev = NULL; // the previous to current element, if we delete in order to go back + //SLIST_FOREACH(so, &flexran_handles[mod_id], entries) + for(so = flexran_handles[mod_id].slh_first; so;) { + char *name = so->name; + int in_use = strcmp(flexran_get_dl_scheduler_name(mod_id), name) == 0 + || strcmp(flexran_get_ul_scheduler_name(mod_id), name) == 0; + Protocol__FlexSliceAlgorithm dl_algo = flexran_get_dl_slice_algo(mod_id); + if (!in_use && dl_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + int n = flexran_get_num_dl_slices(mod_id); + for (int i = 0; i < n; ++i) { + Protocol__FlexSlice s; + /* NONE so it won't do any allocations */ + flexran_get_dl_slice(mod_id, i, &s, PROTOCOL__FLEX_SLICE_ALGORITHM__None); + if (strcmp(s.scheduler, name) == 0) { + in_use = 1; + break; + } + } + } + Protocol__FlexSliceAlgorithm ul_algo = flexran_get_ul_slice_algo(mod_id); + if (!in_use && ul_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + int n = flexran_get_num_ul_slices(mod_id); + for (int i = 0; i < n; ++i) { + Protocol__FlexSlice s; + /* NONE so it won't do any allocations */ + flexran_get_ul_slice(mod_id, i, &s, PROTOCOL__FLEX_SLICE_ALGORITHM__None); + if (strcmp(s.scheduler, name) == 0) { + in_use = 1; + break; + } + } + } + if (!in_use) { + char s[512]; + int rc = flexran_agent_map_name_to_delegated_object(mod_id, so->name, s, 512); + LOG_W(FLEXRAN_AGENT, + "removing %s (library handle %p) since it is not used in the user " + "plane anymore\n", + s, + so->dl_handle); + dlclose(so->dl_handle); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, "cannot map name %s\n", so->name); + } else { + int rc = remove(s); + if (rc < 0) + LOG_E(FLEXRAN_AGENT, "cannot remove file %s: %s\n", s, strerror(errno)); + } + free (so->name); + if (!prev) { //it's the head, start over + SLIST_REMOVE_HEAD(&flexran_handles[mod_id], entries); + so = flexran_handles[mod_id].slh_first; + } else { + SLIST_REMOVE(&flexran_handles[mod_id], so, flexran_agent_so_handle_s, entries); + so = prev->entries.sle_next; + } + } else { + prev = so; + so = so->entries.sle_next; + } + } } Protocol__FlexUeConfig *ue_config = NULL; @@ -1765,3 +1988,92 @@ void flexran_agent_slice_update(mid_t mod_id) { free(ue_config); } } + +void flexran_agent_mac_inform_delegation(mid_t mod_id, + Protocol__FlexControlDelegation *cdm) { + LOG_W(FLEXRAN_AGENT, + "received FlexControlDelegation message for object '%s' xid %d\n", + cdm->name, + cdm->header->xid); + if (cdm->header->xid < xid - 1) { + LOG_I(FLEXRAN_AGENT, + "waiting for %d more messages (up to xid %d)\n", + xid - 1 - cdm->header->xid, + xid - 1); + return; + } + /* should receive up to xid - 1, otherwise it means there was no request */ + AssertFatal(xid > cdm->header->xid, + "received control delegation with xid %d that we never requested " + "(last request %d)\n", + cdm->header->xid, + xid - 1); + + /* Load the library so the user plane can search it */ + char s[512]; + int rc = flexran_agent_map_name_to_delegated_object(mod_id, cdm->name, s, 512); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, "cannot map name %s\n", cdm->name); + return; + } + /* TODO where to unload/save handle?? */ + void *h = dlopen(s, RTLD_NOW); + if (!h) { + LOG_E(FLEXRAN_AGENT, "dlopen(): %s\n", dlerror()); + return; + } + LOG_I(FLEXRAN_AGENT, "library handle %p\n", h); + + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + + Protocol__FlexranMessage *msg = NULL; + struct lfds700_ringbuffer_state *state = &store_slice_config_ringbuffer_state[mod_id]; + if (lfds700_ringbuffer_read(state, NULL, (void **) &msg, &ls) == 0) { + LOG_E(FLEXRAN_AGENT, "%s(): could not read config from ringbuffer\n", __func__); + return; + } + AssertFatal(cdm->header->xid == msg->enb_config_reply_msg->header->xid, + "expected and retrieved xid of stored slice configuration does " + "not match (expected %d, retrieved %d)\n", + cdm->header->xid, + msg->enb_config_reply_msg->header->xid); + + /* Since we recover, stop the timeout */ + rc = flexran_agent_destroy_timer(mod_id, cdm->header->xid); + + prepare_update_slice_config( + mod_id, + &msg->enb_config_reply_msg->cell_config[0]->slice_config, + 0 /* don't do a request */); + /* we should not call flexran_agent_destroy_enb_config_reply(smsg); since + * upon timer removal, this is automatically done. + * prepare_update_slice_config() takes ownership of the slice config, it is + * freed inside */ + + flexran_agent_so_handle_t *so = malloc(sizeof(flexran_agent_so_handle_t)); + DevAssert(so); + so->name = strdup(cdm->name); + DevAssert(so->name); + so->dl_handle = h; + SLIST_INSERT_HEAD(&flexran_handles[mod_id], so, entries); +} + +void flexran_agent_mac_fill_loaded_mac_objects( + mid_t mod_id, + Protocol__FlexEnbConfigReply *reply) { + int n = 0; + flexran_agent_so_handle_t *so = NULL; + SLIST_FOREACH(so, &flexran_handles[mod_id], entries) + ++n; + reply->n_loadedmacobjects = n; + reply->loadedmacobjects = calloc(n, sizeof(char *)); + if (!reply->loadedmacobjects) { + reply->n_loadedmacobjects = 0; + return; + } + n = 0; + SLIST_FOREACH(so, &flexran_handles[mod_id], entries) + reply->loadedmacobjects[n++] = so->name; +} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 5a8d4f31aa..18e567c061 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -39,6 +39,12 @@ // for flexran_agent_get_mac_xface() #include "flexran_agent_extern.h" +/* Type for a list of shared objects used in the user plane (schedulers) */ +typedef struct flexran_agent_so_handle_s { + char *name; // name of the object + void *dl_handle; // handle of associated objects + SLIST_ENTRY (flexran_agent_so_handle_s) entries; +} flexran_agent_so_handle_t; /* Initialization function for the agent structures etc */ void flexran_agent_init_mac_agent(mid_t mod_id); @@ -117,7 +123,9 @@ void flexran_agent_slice_update(mid_t mod_id); /* marks slice_config so that it can be applied later. Takes ownership of the * FlexSliceConfig message */ -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice); +void prepare_update_slice_config(mid_t mod_id, + Protocol__FlexSliceConfig **slice, + int request_objects); /* inserts a new ue_config into the structure keeping ue to slice association * updates and marks so it can be applied. Takes ownership of the FlexUeConfig message */ @@ -127,4 +135,13 @@ void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_con * flexran_agent_fill_mac_cell_config() */ void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf); +/* information about a new (potentially relevant) control delegation message */ +void flexran_agent_mac_inform_delegation(mid_t mod_id, + Protocol__FlexControlDelegation *cdm); + +/* fill the enb_config_reply with the shared objects in use by the MAC sublayer */ +void flexran_agent_mac_fill_loaded_mac_objects( + mid_t mod_id, + Protocol__FlexEnbConfigReply *reply); + #endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 93de0b11ec..42246c3ebf 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -33,6 +33,9 @@ #include "flexran_agent_mac_internal.h" #include "flexran_agent_mac_slice_verification.h" +extern SLIST_HEAD(flexran_so_handle, + flexran_agent_so_handle_s) flexran_handles[NUM_MAX_ENB]; + Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message, Protocol__FlexranMessage *old_message) { @@ -1025,6 +1028,19 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { } +void *search_so(mid_t mod_id, char *name) { + if (!name) // no name -> nothing to return, so use NULL for executable + return NULL; + if (dlsym(NULL, name)) // found it in executable + return NULL; + flexran_agent_so_handle_t *so = NULL; + SLIST_FOREACH(so, &flexran_handles[mod_id], entries) { + if (strcmp(so->name, name) == 0) + return so->dl_handle; + } + return NULL; +} + void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) { if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET && !s->label && !s->scheduler) { @@ -1033,8 +1049,12 @@ void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) { if (!rc) LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id); } else { - LOG_I(FLEXRAN_AGENT, "updating DL slice ID %d\n", s->id); - const int rc = flexran_create_dl_slice(mod_id, s); + void *lib = search_so(mod_id, s->scheduler); + LOG_I(FLEXRAN_AGENT, + "updating DL slice ID %d (library handle %p)\n", + s->id, + lib); + const int rc = flexran_create_dl_slice(mod_id, s, lib); if (rc < 0) LOG_W(FLEXRAN_AGENT, "error while update slice ID %d: flexran_create_dl_slice() -> %d\n", @@ -1050,8 +1070,12 @@ void update_or_remove_ul(mid_t mod_id, Protocol__FlexSlice *s) { if (!rc) LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id); } else { - LOG_I(FLEXRAN_AGENT, "updating UL slice ID %d\n", s->id); - const int rc = flexran_create_ul_slice(mod_id, s); + void *lib = search_so(mod_id, s->scheduler); + LOG_I(FLEXRAN_AGENT, + "updating UL slice ID %d (library handle %p)\n", + s->id, + lib); + const int rc = flexran_create_ul_slice(mod_id, s, lib); if (rc < 0) LOG_W(FLEXRAN_AGENT, "error while updating slice ID %d: flexran_create_ul_slice() -> %d)\n", @@ -1099,8 +1123,12 @@ void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *d LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n"); return; } - LOG_I(FLEXRAN_AGENT, "loading DL new scheduling algorithm '%s'\n", dl->scheduler); - const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler); + void *lib = search_so(mod_id, dl->scheduler); + LOG_I(FLEXRAN_AGENT, + "loading DL new scheduling algorithm '%s' (library handle %p)\n", + dl->scheduler, + lib); + const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler, lib); if (rc < 0) { LOG_E(FLEXRAN_AGENT, "error while updating scheduling algorithm: " @@ -1147,8 +1175,12 @@ void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *u LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n"); return; } - LOG_I(FLEXRAN_AGENT, "loading new UL scheduling algorithm '%s'\n", ul->scheduler); - const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler); + void *lib = search_so(mod_id, ul->scheduler); + LOG_I(FLEXRAN_AGENT, + "loading new UL scheduling algorithm '%s' (library handle %p)\n", + ul->scheduler, + lib); + const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler, lib); if (rc < 0) { LOG_E(FLEXRAN_AGENT, "error while updating scheduling algorithm: " diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h index 72e77c3800..c4e6670ea3 100644 --- a/openair2/ENB_APP/L1_paramdef.h +++ b/openair2/ENB_APP/L1_paramdef.h @@ -61,6 +61,7 @@ #define CONFIG_STRING_L1_PRACH_DTX_EMTC3_THRESHOLD "prach_dtx_emtc3_threshold" #define CONFIG_STRING_L1_PUCCH1_DTX_EMTC3_THRESHOLD "pucch1_dtx_emtc3_threshold" #define CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC3_THRESHOLD "pucch1ab_dtx_emtc3_threshold" +#define CONFIG_STRING_L1_PUSCH_SIGNAL_THRESHOLD "pusch_signal_threshold" /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* L1 configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -89,7 +90,8 @@ {CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC2_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0}, \ {CONFIG_STRING_L1_PRACH_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_STRING_L1_PUCCH1_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ - {CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0} \ +{CONFIG_STRING_L1_PUCCH1AB_DTX_EMTC3_THRESHOLD, NULL, 0, iptr:NULL, defintval:4, TYPE_INT, 0}, \ +{CONFIG_STRING_L1_PUSCH_SIGNAL_THRESHOLD, NULL, 0, iptr:NULL, defintval:635, TYPE_INT, 0} \ } #define L1_CC_IDX 0 #define L1_TRANSPORT_N_PREFERENCE_IDX 1 @@ -115,6 +117,7 @@ #define L1_PRACH_DTX_EMTC3_THRESHOLD_IDX 21 #define L1_PUCCH1_DTX_EMTC3_THRESHOLD_IDX 22 #define L1_PUCCH1AB_DTX_EMTC3_THRESHOLD_IDX 23 +#define L1_PUSCH_SIGNAL_THRESHOLD_IDX 24 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto index ef0eea3bd2..a646a978a9 100644 --- a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto +++ b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto @@ -3,4 +3,25 @@ package protocol; enum flex_control_delegation_type { FLCDT_MAC_DL_UE_SCHEDULER = 1; // DL UE scheduler delegation + FLCDT_AGENT_CONTROL_APP = 2; // Generic control application +} + +message flex_agent_reconfiguration_system { + optional string system = 1; + repeated flex_agent_reconfiguration_subsystem subsystems = 2; +} + +message flex_agent_reconfiguration_subsystem { + optional string name = 1; // Name of the object (app name or user plane object) + optional string behavior = 2; // For an app: a callback in a shared library. For any other subsystem: an object name (shared library) with defined syntax. + map params = 3; // Param configurations depending on callback/shared library above. +} + +message flex_agent_reconfiguration_param { + oneof param { + int32 integer = 1; + float floating = 2; + bool boolean = 3; + string str = 4; + } } diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto index 3b47ff263b..cec7f84b6e 100644 --- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto +++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto @@ -7,6 +7,7 @@ import "time_common.proto"; import "config_messages.proto"; import "controller_commands.proto"; import "config_common.proto"; +import "control_delegation.proto"; message flexran_message { optional flexran_direction msg_dir = 100; @@ -32,6 +33,7 @@ message flexran_message { flex_ul_mac_config ul_mac_config_msg = 19; flex_disconnect disconnect_msg = 20; flex_ho_command ho_command_msg = 21; + flex_control_delegation_request control_del_req_msg = 22; } } @@ -157,6 +159,8 @@ message flex_enb_config_reply { repeated flex_cell_config cell_config = 3; optional uint32 device_spec = 4; optional flex_s1ap_config s1ap = 5; + repeated string loadedApps = 6; + repeated string loadedMacObjects = 7; } message flex_ue_config_request { @@ -225,11 +229,17 @@ message flex_ue_state_change { message flex_control_delegation { optional flex_header header = 1; - optional uint32 delegation_type = 2; // Bitmap of FLCDT_* flags + optional flex_control_delegation_type delegation_type = 2; // The delegated object type, decides about further processing optional bytes payload = 3; // Byte array of shared lib containing the delegated functions optional string name = 4; // The delegated functions names ordered based on bitmap flags } +message flex_control_delegation_request { + optional flex_header header = 1; + optional flex_control_delegation_type delegation_type = 2; + optional string name = 4; +} + // // Agent reconfiguration message // @@ -237,6 +247,7 @@ message flex_control_delegation { message flex_agent_reconfiguration { optional flex_header header = 1; optional string policy = 2; // The policy changes using YAML syntax in string format + repeated flex_agent_reconfiguration_system systems = 3; // The policy changes. } // Extensions of the echo request and reply diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto index 41b2b37f7a..5e224f64f7 100644 --- a/openair2/ENB_APP/MESSAGES/V2/header.proto +++ b/openair2/ENB_APP/MESSAGES/V2/header.proto @@ -44,5 +44,6 @@ enum flex_type { FLPT_RECONFIGURE_AGENT = 16; FLPT_RRC_TRIGGERING = 17; FLPT_UL_MAC_CONFIG = 18; + FLPT_DELEGATE_REQUEST = 22; } diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 1d001022d2..5080157c3f 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -70,7 +70,7 @@ extern RAN_CONTEXT_t RC; // for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { // { // -// //msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); +// //msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, S1AP_REGISTER_ENB_REQ); // //RCconfig_S1(msg_p, enb_id); // // if (enb_id == 0) RCconfig_gtpu(); @@ -93,14 +93,14 @@ static uint32_t eNB_app_register_m2(uint32_t enb_id_start, uint32_t enb_id_end) MessageDef *msg_p; uint32_t register_enb_m2_pending = 0; -// msg_p = itti_alloc_new_message (TASK_ENB_APP,MESSAGE_TEST ); +// msg_p = itti_alloc_new_message (TASK_ENB_APP, 0,MESSAGE_TEST ); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); LOG_D(ENB_APP,"Register ...\n"); for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { { - msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_REGISTER_ENB_REQ); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, M2AP_REGISTER_ENB_REQ); RCconfig_M2(msg_p, enb_id); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); register_enb_m2_pending++; @@ -115,28 +115,28 @@ static uint32_t eNB_app_register_m2(uint32_t enb_id_start, uint32_t enb_id_end) static uint32_t eNB_app_handle_m2ap_mbms_scheduling_information(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; } static uint32_t eNB_app_handle_m2ap_mbms_session_start_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_START_RESP); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, M2AP_MBMS_SESSION_START_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; } static uint32_t eNB_app_handle_m2ap_mbms_session_stop_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_STOP_RESP); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, M2AP_MBMS_SESSION_STOP_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; } static uint32_t eNB_app_handle_m2ap_mbms_session_update_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_UPDATE_RESP); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, M2AP_MBMS_SESSION_UPDATE_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; } @@ -155,7 +155,7 @@ static uint32_t eNB_app_register(ngran_node_t node_type,uint32_t enb_id_start, u if (NODE_IS_DU(node_type)) { // F1AP registration // configure F1AP here for F1C LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); - msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, F1AP_SETUP_REQ); RCconfig_DU_F1(msg_p, enb_id); LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); @@ -164,7 +164,7 @@ static uint32_t eNB_app_register(ngran_node_t node_type,uint32_t enb_id_start, u } else { // S1AP registration /* note: there is an implicit relationship between the data structure and the message name */ - msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, S1AP_REGISTER_ENB_REQ); RCconfig_S1(msg_p, enb_id); if (enb_id == 0) RCconfig_gtpu(); @@ -191,7 +191,7 @@ static uint32_t eNB_app_register_x2(uint32_t enb_id_start, uint32_t enb_id_end) for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) { { - msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); + msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, X2AP_REGISTER_ENB_REQ); RCconfig_X2(msg_p, enb_id); itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); register_enb_x2_pending++; @@ -247,7 +247,7 @@ void *eNB_app_task(void *args_p) { do { // Wait for a message itti_receive_msg (TASK_ENB_APP, &msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -266,7 +266,7 @@ void *eNB_app_task(void *args_p) { case S1AP_REGISTER_ENB_CNF: AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n"); if (EPC_MODE_ENABLED) { - LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_I(ENB_APP, "[eNB %ld] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); register_enb_pending--; @@ -280,7 +280,7 @@ void *eNB_app_task(void *args_p) { if (registered_enb == enb_nb) { /* If all eNB are registered, start L2L1 task */ MessageDef *msg_init_p; - msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + msg_init_p = itti_alloc_new_message (TASK_ENB_APP, 0, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); } else { LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n", @@ -323,7 +323,7 @@ void *eNB_app_task(void *args_p) { /* If all eNB cells are registered, start L2L1 task */ MessageDef *msg_init_p; - msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + msg_init_p = itti_alloc_new_message (TASK_ENB_APP, 0, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); } else { @@ -347,7 +347,7 @@ void *eNB_app_task(void *args_p) { case S1AP_DEREGISTERED_ENB_IND: if (EPC_MODE_ENABLED) { - LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_W(ENB_APP, "[eNB %ld] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme); /* TODO handle recovering of registration */ } @@ -380,13 +380,13 @@ void *eNB_app_task(void *args_p) { break; case X2AP_DEREGISTERED_ENB_IND: - LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_W(ENB_APP, "[eNB %ld] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), X2AP_DEREGISTERED_ENB_IND(msg_p).nb_x2); /* TODO handle recovering of registration */ break; case X2AP_REGISTER_ENB_CNF: - LOG_I(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_I(ENB_APP, "[eNB %ld] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), X2AP_REGISTER_ENB_CNF(msg_p).nb_x2); DevAssert(x2_register_enb_pending > 0); x2_register_enb_pending--; @@ -422,13 +422,13 @@ void *eNB_app_task(void *args_p) { break; case M2AP_DEREGISTERED_ENB_IND: - LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_W(ENB_APP, "[eNB %ld] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2); /* TODO handle recovering of registration */ break; case M2AP_REGISTER_ENB_CNF: - LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_W(ENB_APP, "[eNB %ld] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p), M2AP_REGISTER_ENB_CNF(msg_p).nb_m2); DevAssert(m2_register_enb_pending > 0); m2_register_enb_pending--; @@ -485,7 +485,7 @@ void *eNB_app_task(void *args_p) { // /* If all eNB cells are registered, start L2L1 task */ // MessageDef *msg_init_p; - // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, 0, INITIALIZE_MESSAGE); // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); // } else { @@ -508,15 +508,15 @@ void *eNB_app_task(void *args_p) { case M2AP_MBMS_SCHEDULING_INFORMATION: LOG_I(ENB_APP,"M2AP_SCHEDULING_INFORMATION received\n"); - eNB_app_handle_m2ap_mbms_scheduling_information(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + eNB_app_handle_m2ap_mbms_scheduling_information(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); break; case M2AP_MBMS_SESSION_START_REQ: LOG_I(ENB_APP,"M2AP_MBMS_SESSION_START_REQ received\n"); - eNB_app_handle_m2ap_mbms_session_start_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + eNB_app_handle_m2ap_mbms_session_start_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); break; case M2AP_MBMS_SESSION_STOP_REQ: LOG_I(ENB_APP,"M2AP_MBMS_SESSION_STOP_REQ received\n"); - eNB_app_handle_m2ap_mbms_session_stop_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + eNB_app_handle_m2ap_mbms_session_stop_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); break; case M2AP_RESET: LOG_I(ENB_APP,"M2AP_RESET received\n"); @@ -529,7 +529,7 @@ void *eNB_app_task(void *args_p) { break; case M2AP_ERROR_INDICATION: LOG_I(ENB_APP,"M2AP_MBMS_SESSION_UPDATE_REQ\n"); - eNB_app_handle_m2ap_mbms_session_update_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + eNB_app_handle_m2ap_mbms_session_update_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); break; case M2AP_MBMS_SERVICE_COUNTING_REQ: LOG_I(ENB_APP,"M2AP_MBMS_SERVICE_COUNTING_REQ\n"); diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index cf8ba78a81..6c709ea63b 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -121,15 +121,14 @@ void RCconfig_L1(void) { RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr); if (RC.eNB[j] == NULL) { - RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *)); + RC.eNB[j] = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *)); LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]); memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB *)); } for (i=0; iMod_id = j; RC.eNB[j][i]->CC_id = i; @@ -170,6 +169,10 @@ void RCconfig_L1(void) { RC.eNB[j][0]->pucch1_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PUCCH1_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr); RC.eNB[j][0]->pucch1ab_DTX_threshold_emtc[ce_level] = *(L1_ParamList.paramarray[j][L1_PUCCH1AB_DTX_EMTC0_THRESHOLD_IDX+ce_level].iptr); } + + + RC.eNB[j][0]->pusch_signal_threshold = *(L1_ParamList.paramarray[j][L1_PUSCH_SIGNAL_THRESHOLD_IDX].iptr); + LOG_I(ENB_APP,"PUSCH singal threshold = %d \n",RC.eNB[j][0]->pusch_signal_threshold); }// j=0..num_inst LOG_I(ENB_APP,"Initializing northbound interface for L1\n"); @@ -287,7 +290,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { int32_t offsetMaxLimit = 0; int32_t cycleNb = 0; - MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_CONFIGURATION_REQ); + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_ENB, 0, RRC_CONFIGURATION_REQ); ccparams_lte_t ccparams_lte; ccparams_sidelink_t SLconfig; ccparams_eMTC_t eMTCconfig; @@ -2051,7 +2054,7 @@ int RCconfig_gtpu(void ) { if (address) { MessageDef *message; - AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, GTPV1U_ENB_S1_REQ))!=NULL,""); + AssertFatal((message = itti_alloc_new_message(TASK_ENB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,""); IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U; @@ -2511,6 +2514,9 @@ int RCconfig_S1( S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0; } + /* set S1-mme port (sctp) */ + S1AP_REGISTER_ENB_REQ(msg_p).mme_port[l] = *S1ParamList.paramarray[l][ENB_MME_PORT_IDX].u16ptr; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, "List of broadcast PLMN to be sent to MME can not be longer than actual " "PLMN list (max %d, but is %d)\n", diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index d2372c944c..de7e0bbdad 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -34,6 +34,7 @@ #define ENB_PARAMDEF_H_ #include "common/config/config_paramdesc.h" #include "RRC_paramsvalues.h" +#include "s1ap_eNB_default_values.h" #define ENB_CONFIG_STRING_CC_NODE_FUNCTION "node_function" #define ENB_CONFIG_STRING_CC_NODE_TIMING "node_timing" @@ -96,6 +97,7 @@ typedef enum { #define CONFIG_STRING_RU_OTA_SYNC_ENABLE "ota_sync_enabled" #define CONFIG_STRING_RU_BF_WEIGHTS_LIST "bf_weights" #define CONFIG_STRING_RU_IF_FREQUENCY "if_freq" +#define CONFIG_STRING_RU_IF_FREQ_OFFSET "if_offset" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -124,6 +126,7 @@ typedef enum { #define RU_OTA_SYNC_ENABLE_IDX 24 #define RU_BF_WEIGHTS_LIST_IDX 25 #define RU_IF_FREQUENCY 26 +#define RU_IF_FREQ_OFFSET 27 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ @@ -157,6 +160,7 @@ typedef enum { {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}, \ {CONFIG_STRING_RU_IF_FREQUENCY, NULL, 0, u64ptr:NULL, defuintval:0, TYPE_UINT64, 0}, \ + {CONFIG_STRING_RU_IF_FREQ_OFFSET, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -907,6 +911,7 @@ typedef struct srb1_params_s { #define ENB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4" #define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6" +#define ENB_CONFIG_STRING_MME_PORT "port" #define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active" #define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference" #define ENB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX "broadcast_plmn_index" @@ -921,14 +926,20 @@ typedef struct srb1_params_s { {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_BROADCAST_PLMN_INDEX, NULL, 0, uptr:NULL, defintarrayval:NULL, TYPE_UINTARRAY, 6}, \ + {ENB_CONFIG_STRING_MME_PORT, NULL, 0, u16ptr:NULL, defuintval:S1AP_PORT_NUMBER, TYPE_UINT16, 0}, \ } + + + + #define ENB_MME_IPV4_ADDRESS_IDX 0 #define ENB_MME_IPV6_ADDRESS_IDX 1 #define ENB_MME_IP_ADDRESS_ACTIVE_IDX 2 #define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3 #define ENB_MME_BROADCAST_PLMN_INDEX 4 +#define ENB_MME_PORT_IDX 5 /*---------------------------------------------------------------------------------------------------------------------------------------*/ /* X2 configuration parameters section name */ diff --git a/openair2/ENB_APP/flexran_agent.c b/openair2/ENB_APP/flexran_agent.c index 519d2bef4b..33182f3593 100644 --- a/openair2/ENB_APP/flexran_agent.c +++ b/openair2/ENB_APP/flexran_agent.c @@ -115,7 +115,6 @@ error: return NULL; } - int channel_container_init = 0; int flexran_agent_start(mid_t mod_id) { @@ -233,6 +232,9 @@ int flexran_agent_start(mid_t mod_id) agent_task_created = 1; } + /* Init the app sublayer */ + flexran_agent_app_init(mod_id); + pthread_mutex_init(&flexran->mutex_node_ctrl, NULL); pthread_cond_init(&flexran->cond_node_ctrl, NULL); @@ -249,7 +251,7 @@ int flexran_agent_start(mid_t mod_id) pthread_mutex_unlock(&flexran->mutex_node_ctrl); /* reconfigure RRC again, the agent might have changed the configuration */ - MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[mod_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg_p); } diff --git a/openair2/ENB_APP/flexran_agent.h b/openair2/ENB_APP/flexran_agent.h index 42295fc111..43e7d7210a 100644 --- a/openair2/ENB_APP/flexran_agent.h +++ b/openair2/ENB_APP/flexran_agent.h @@ -41,6 +41,7 @@ #include "flexran_agent_rrc.h" #include "flexran_agent_pdcp.h" #include "flexran_agent_s1ap.h" +#include "flexran_agent_app.h" #include "common/utils/LOG/log.h" #include "assertions.h" diff --git a/openair2/ENB_APP/flexran_agent_app.c b/openair2/ENB_APP/flexran_agent_app.c new file mode 100644 index 0000000000..5bf06ca631 --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_app.c @@ -0,0 +1,207 @@ +/* + * 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 flexran_agent_app.c + * \brief CM for handling of applications + * \author Robert Schmidt + * \date 2020 + * \version 0.1 + */ + +#include "flexran_agent_app.h" +#include "queue.h" +#include + +/* app definition */ +typedef struct flexran_agent_app_internal_s { + char *name; + void *dl_handle; + flexran_agent_app_t *app; + + SLIST_ENTRY (flexran_agent_app_internal_s) entries; +} flexran_agent_app_internal_t; + +/* a list of all apps */ +SLIST_HEAD(flexran_apps_s, flexran_agent_app_internal_s) flexran_apps[NUM_MAX_ENB]; + +void flexran_agent_app_init(mid_t mod_id) { + //flexran_apps[mod_id] = SLIST_HEAD_INITIALIZER(flexran_apps[mod_id]); + SLIST_INIT(&flexran_apps[mod_id]); +} + +int flexran_agent_start_app_direct(mid_t mod_id, flexran_agent_app_t *app, char *name) { + app->start(mod_id, NULL, 0); + + flexran_agent_app_internal_t *so = malloc(sizeof(flexran_agent_app_internal_t)); + DevAssert(so); + so->name = strdup(name); + DevAssert(so->name); + so->dl_handle = NULL; + so->app = app; + SLIST_INSERT_HEAD(&flexran_apps[mod_id], so, entries); + return 0; +} + +int flexran_agent_start_app(mid_t mod_id, Protocol__FlexAgentReconfigurationSubsystem *sub) { + char s[512]; + int rc = flexran_agent_map_name_to_delegated_object(mod_id, sub->name, s, 512); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, "cannot map name %s\n", sub->name); + return -1; + } + void *h = dlopen(s, RTLD_NOW); + if (!h) { + LOG_E(FLEXRAN_AGENT, "cannot open shared object %s\n", s); + return -1; + } + flexran_agent_app_t *app = dlsym(h, "app"); + if (!app) { + LOG_E(FLEXRAN_AGENT, "cannot locate app inside of shared object %s\n", s); + return -1; + } + app->start(mod_id, sub->params, sub->n_params); + + flexran_agent_app_internal_t *so = malloc(sizeof(flexran_agent_app_internal_t)); + DevAssert(so); + so->name = strdup(sub->name); + DevAssert(so->name); + so->dl_handle = h; + so->app = app; + SLIST_INSERT_HEAD(&flexran_apps[mod_id], so, entries); + + return 0; +} + +int flexran_agent_stop_app(mid_t mod_id, char *name) { + flexran_agent_app_internal_t *so = NULL; + SLIST_FOREACH(so, &flexran_apps[mod_id], entries) { + if (strcmp(so->name, name) == 0) { + LOG_I(FLEXRAN_AGENT, "application %s seems to be running\n", name); + break; + } + } + if (!so) { + LOG_E(FLEXRAN_AGENT, "no such application %s found\n", name); + return -1; + } + flexran_agent_app_t *app = so->app; + app->stop(mod_id); + + SLIST_REMOVE(&flexran_apps[mod_id], so, flexran_agent_app_internal_s, entries); + free(so->name); + if (so->dl_handle) + dlclose(so->dl_handle); + free(so); + so = NULL; + return 0; +} + +int flexran_agent_reconfig_app( + mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem *sub) +{ + flexran_agent_app_internal_t *so = NULL; + SLIST_FOREACH(so, &flexran_apps[mod_id], entries) { + if (strcmp(so->name, sub->name) == 0) { + LOG_I(FLEXRAN_AGENT, "application %s is running\n", sub->name); + break; + } + } + if (!so) { + LOG_E(FLEXRAN_AGENT, "no such application %s found\n", sub->name); + return -1; + } + flexran_agent_app_t *app = so->app; + LOG_I(FLEXRAN_AGENT, "reconfiguring app %s\n", so->name); + app->reconfig(mod_id, sub->params, sub->n_params); + return 0; +} + +int flexran_agent_custom_command_app( + mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem *sub) +{ + flexran_agent_app_internal_t *so = NULL; + SLIST_FOREACH(so, &flexran_apps[mod_id], entries) { + if (strcmp(so->name, sub->name) == 0) { + LOG_I(FLEXRAN_AGENT, "application %s is running\n", sub->name); + break; + } + } + if (!so) { + LOG_E(FLEXRAN_AGENT, "no such application %s found\n", sub->name); + return -1; + } + void (*cmd)(mid_t, Protocol__FlexAgentReconfigurationSubsystem *) = dlsym(so->dl_handle, sub->behavior); + if (!cmd) { + LOG_E(FLEXRAN_AGENT, + "cannot locate command %s inside of app %s\n", + sub->behavior, + so->name); + return -1; + } + + LOG_I(FLEXRAN_AGENT, + "calling command %s inside of app %s\n", + sub->behavior, + so->name); + (*cmd)(mod_id, sub); + return 0; +} + +void flexran_agent_handle_apps( + mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem **subs, + int n_subs) { + for (int i = 0; i < n_subs; ++i) { + Protocol__FlexAgentReconfigurationSubsystem *s = subs[i]; + if (strcmp(s->behavior, "start") == 0) { + int rc = flexran_agent_start_app(mod_id, s); + if (rc == 0) + LOG_I(FLEXRAN_AGENT, "application \"%s\" started\n", s->name); + } else if (strcmp(s->behavior, "stop") == 0) { + int rc = flexran_agent_stop_app(mod_id, s->name); + if (rc == 0) + LOG_I(FLEXRAN_AGENT, "application \"%s\" stopped\n", s->name); + } else if (strcmp(s->behavior, "reconfig") == 0) { + flexran_agent_reconfig_app(mod_id, s); + } else { + flexran_agent_custom_command_app(mod_id, s); + } + } +} + +void flexran_agent_fill_loaded_apps(mid_t mod_id, + Protocol__FlexEnbConfigReply *reply) { + int n = 0; + flexran_agent_app_internal_t *so = NULL; + SLIST_FOREACH(so, &flexran_apps[mod_id], entries) + ++n; + reply->n_loadedapps = n; + reply->loadedapps = calloc(n, sizeof(char *)); + if (!reply->loadedapps) { + reply->n_loadedapps = 0; + return; + } + n = 0; + SLIST_FOREACH(so, &flexran_apps[mod_id], entries) + reply->loadedapps[n++] = so->name; +} diff --git a/openair2/ENB_APP/flexran_agent_app.h b/openair2/ENB_APP/flexran_agent_app.h new file mode 100644 index 0000000000..4723b344bf --- /dev/null +++ b/openair2/ENB_APP/flexran_agent_app.h @@ -0,0 +1,74 @@ +/* + * 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 flexran_agent_app.h + * \brief Common app definitions + * \author Robert Schmidt + * \date 2020 + * \version 0.1 + */ + +#ifndef BURST_ANALYSIS_LL_H_ +#define BURST_ANALYSIS_LL_H_ + +#include "flexran_agent_common.h" +#include "flexran_agent_async.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_net_comm.h" +#include "flexran_agent_ran_api.h" +#include "flexran_agent_phy.h" +#include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" +#include "flexran_agent_s1ap.h" +#include "common/utils/LOG/log.h" +#include "assertions.h" + +/* App type: to be implemented by shared libraries */ +typedef struct { + int (*start)(mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, + int n_p); + int (*reconfig)(mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, + int n_p); + int (* stop)(mid_t mod_id); +} flexran_agent_app_t; + +/* FlexRAN agent app handling init */ +void flexran_agent_app_init(mid_t mod_id); + +/* Start an app from within the agent */ +int flexran_agent_start_app_direct(mid_t mod_id, flexran_agent_app_t *app, char *name); + +/* FlexRAN agent handler to setup/teardown apps */ +void flexran_agent_handle_apps( + mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem **subs, + int n_subs); + +/* Fills the enb_config_reply with the currently loaded (started) apps */ +void flexran_agent_fill_loaded_apps(mid_t mod_id, + Protocol__FlexEnbConfigReply *reply); + +#endif diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 7569ca1ac1..abb5b57e0c 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include "flexran_agent_common.h" #include "flexran_agent_common_internal.h" @@ -39,6 +42,7 @@ #include "flexran_agent_mac.h" #include "flexran_agent_rrc.h" #include "flexran_agent_s1ap.h" +#include "flexran_agent_app.h" //#include "PHY/extern.h" #include "common/utils/LOG/log.h" #include "flexran_agent_mac_internal.h" @@ -326,6 +330,12 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { if (reply->s1ap) flexran_agent_free_s1ap_cell_config(&reply->s1ap); + if (reply->loadedapps) + free(reply->loadedapps); + + if (reply->loadedmacobjects) + free(reply->loadedmacobjects); + free(reply->cell_config); free(reply); free(msg); @@ -424,26 +434,65 @@ long timer_end(struct timespec start_time) { int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexControlDelegation *control_delegation_msg = input->control_delegation_msg; - // struct timespec vartime = timer_start(); - //Write the payload lib into a file in the cache and load the lib - char lib_name[120]; - char target[512]; - snprintf(lib_name, sizeof(lib_name), "/%s.so", control_delegation_msg->name); - strcpy(target, RC.flexran[mod_id]->cache_name); - strcat(target, lib_name); - FILE *f; - f = fopen(target, "wb"); + *msg = NULL; - if (f) { - fwrite(control_delegation_msg->payload.data, control_delegation_msg->payload.len, 1, f); - fclose(f); + char target[512]; + int len = snprintf(target, sizeof(target), "%s/libflex.%s.so", + RC.flexran[mod_id]->cache_name, + control_delegation_msg->name); + if (len >= sizeof(target)) { + LOG_E(FLEXRAN_AGENT, "target has been truncated, cannot write file name\n"); + return 0; + } + + if (control_delegation_msg->has_payload) { + /* use low-level API: check whether exists while creating so we can abort if + * it exists to not overwrite anything */ + int fd = open(target, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR); + if (fd >= 0) { + ssize_t l = write(fd, + control_delegation_msg->payload.data, + control_delegation_msg->payload.len); + close(fd); + if (l < control_delegation_msg->payload.len) { + LOG_E(FLEXRAN_AGENT, + "could not write complete control delegation to %s: only %ld out of " + "%ld bytes\n", + target, + l, + control_delegation_msg->payload.len); + return 0; + } else if (l < 0) { + LOG_E(FLEXRAN_AGENT, "can not write control delegation data to %s: %s\n", + target, strerror(errno)); + return 0; + } + LOG_I(FLEXRAN_AGENT, "wrote shared object %s\n", target); + } else { + if (errno == EEXIST) { + LOG_W(FLEXRAN_AGENT, "file %s already exists, remove it first\n", target); + } else { + LOG_E(FLEXRAN_AGENT, "can not write control delegation data to %s: %s\n", + target, strerror(errno)); + } + return 0; + } } else { - LOG_W(FLEXRAN_AGENT, "[%d] can not write control delegation data to %s\n", - mod_id, target); + LOG_W(FLEXRAN_AGENT, "remove file %s\n", target); + int rc = remove(target); + if (rc < 0) + LOG_E(FLEXRAN_AGENT, "cannot remove file %s: %s\n", target, strerror(errno)); + } + + if (control_delegation_msg->has_delegation_type + && control_delegation_msg->delegation_type == PROTOCOL__FLEX_CONTROL_DELEGATION_TYPE__FLCDT_MAC_DL_UE_SCHEDULER + && control_delegation_msg->header + && control_delegation_msg->header->has_xid) { + /* Inform the MAC subsystem that a control delegation for it has arrived */ + /* TODO this should be triggered by an agent reconfiguration? */ + flexran_agent_mac_inform_delegation(mod_id, control_delegation_msg); } - // long time_elapsed_nanos = timer_end(vartime); - *msg = NULL; return 0; } @@ -452,10 +501,44 @@ int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg) { return 0; } +int flexran_agent_map_name_to_delegated_object(mid_t mod_id, const char *name, + char *path, int maxlen) { + int len = snprintf(path, maxlen, "%s/libflex.%s.so", + RC.flexran[mod_id]->cache_name, name); + if (len >= maxlen) { + LOG_E(FLEXRAN_AGENT, "path has been truncated, cannot read object\n"); + return -1; + } + + struct stat buf; + int status = stat(path, &buf); + if (status < 0) { + LOG_E(FLEXRAN_AGENT, "Could not stat object %s: %s\n", path, strerror(errno)); + return -1; + } + return 0; +} + int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexAgentReconfiguration *agent_reconfiguration_msg = input->agent_reconfiguration_msg; - apply_reconfiguration_policy(mod_id, agent_reconfiguration_msg->policy, strlen(agent_reconfiguration_msg->policy)); + if (agent_reconfiguration_msg->policy) { + /* for compatibility: call old YAML configuration code, although we don't + * use it anymore */ + apply_reconfiguration_policy(mod_id, + agent_reconfiguration_msg->policy, + strlen(agent_reconfiguration_msg->policy)); + } + for (int i = 0; i < agent_reconfiguration_msg->n_systems; ++i) { + const Protocol__FlexAgentReconfigurationSystem *sys = agent_reconfiguration_msg->systems[i]; + if (strcmp(sys->system, "app") == 0) { + flexran_agent_handle_apps(mod_id, sys->subsystems, sys->n_subsystems); + } else { + LOG_E(FLEXRAN_AGENT, + "unknown system name %s in flex_agent_reconfiguration message\n", + sys->system); + } + } *msg = NULL; return 0; } @@ -465,6 +548,15 @@ int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg) { return 0; } +int flexran_agent_destroy_control_delegation_request(Protocol__FlexranMessage *msg) { + if(msg->msg_case != PROTOCOL__FLEXRAN_MESSAGE__MSG_CONTROL_DEL_REQ_MSG) + return -1; + + free(msg->control_del_req_msg->header); + free(msg->control_del_req_msg->name); + free(msg); + return 0; +} int flexran_agent_lc_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { xid_t xid; @@ -750,6 +842,10 @@ int flexran_agent_enb_config_reply(mid_t mod_id, const void *params, Protocol__F if (flexran_agent_get_s1ap_xface(mod_id)) flexran_agent_fill_s1ap_cell_config(mod_id, &enb_config_reply_msg->s1ap); + flexran_agent_fill_loaded_apps(mod_id, enb_config_reply_msg); + + flexran_agent_mac_fill_loaded_mac_objects(mod_id, enb_config_reply_msg); + *msg = malloc(sizeof(Protocol__FlexranMessage)); if(*msg == NULL) { @@ -880,7 +976,9 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (enb_config->n_cell_config > 0) { if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { - prepare_update_slice_config(mod_id, &enb_config->cell_config[0]->slice_config); + prepare_update_slice_config(mod_id, + &enb_config->cell_config[0]->slice_config, + 1 /* request objects if necessary */); } if (enb_config->cell_config[0]->has_eutra_band && enb_config->cell_config[0]->has_dl_freq diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h index fe7b49107c..ae690c7124 100644 --- a/openair2/ENB_APP/flexran_agent_common.h +++ b/openair2/ENB_APP/flexran_agent_common.h @@ -131,11 +131,20 @@ int flexran_agent_destroy_lc_config_request(Protocol__FlexranMessage *msg); /* Control delegation message constructor and destructor */ int flexran_agent_control_delegation(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_control_delegation(Protocol__FlexranMessage *msg); +/* Map a name from a control_delegation message to a file name. The function + * stat()s the file to check existence and returns the complete path name in + * path. The length in path needs to be maxlen, the maximum length the path may + * have. */ +int flexran_agent_map_name_to_delegated_object(mid_t mod_id, const char *name, + char *path, int maxlen); /* Policy reconfiguration message constructor and destructor */ int flexran_agent_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_agent_reconfiguration(Protocol__FlexranMessage *msg); +/* Policy reconfiguration request message destructor */ +int flexran_agent_destroy_control_delegation_request(Protocol__FlexranMessage *msg); + /* rrc triggering measurement message constructor and destructor */ int flexran_agent_rrc_reconfiguration(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg); int flexran_agent_destroy_rrc_reconfiguration(Protocol__FlexranMessage *msg); diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c index 9091753f9a..a893982824 100644 --- a/openair2/ENB_APP/flexran_agent_common_internal.c +++ b/openair2/ENB_APP/flexran_agent_common_internal.c @@ -565,6 +565,6 @@ void initiate_soft_restart(module_id_t mod_id, Protocol__FlexCellConfig *c) } MessageDef *msg; - msg = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SOFT_RESTART_MESSAGE); + msg = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, SOFT_RESTART_MESSAGE); itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } diff --git a/openair2/ENB_APP/flexran_agent_handler.c b/openair2/ENB_APP/flexran_agent_handler.c index d991078cf7..addcd6a142 100644 --- a/openair2/ENB_APP/flexran_agent_handler.c +++ b/openair2/ENB_APP/flexran_agent_handler.c @@ -32,6 +32,7 @@ #include "flexran_agent_rrc.h" #include "flexran_agent_pdcp.h" #include "flexran_agent_s1ap.h" +#include "flexran_agent_app.h" #include "flexran_agent_timer.h" #include "flexran_agent_ran_api.h" #include "common/utils/LOG/log.h" @@ -80,6 +81,11 @@ flexran_agent_message_destruction_callback message_destruction_callback[] = { flexran_agent_destroy_ue_state_change, flexran_agent_destroy_control_delegation, flexran_agent_destroy_agent_reconfiguration, + NULL, /* flex_rrc_triggering */ + NULL, /* flex_ul_mac_config */ + NULL, /* flex_disconnect */ + NULL, /* flex_ho_command */ + flexran_agent_destroy_control_delegation_request, }; /* static const char *flexran_agent_direction2String[] = { */ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 79c992a4d7..ff21971810 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3092,12 +3092,13 @@ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { return slices->s[idx]->id; } -void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; +int flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { + if (!mac_is_present(mod_id)) return 0; int idx = flexran_find_dl_slice(mod_id, slice_id); - if (idx < 0) return; + if (idx < 0) return 0; pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; dl->move_UE(dl->slices, ue_id, idx); + return 1; } int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { @@ -3108,15 +3109,16 @@ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { return slices->s[idx]->id; } -void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; +int flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { + if (!mac_is_present(mod_id)) return 0; int idx = flexran_find_ul_slice(mod_id, slice_id); - if (idx < 0) return; + if (idx < 0) return 0; pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; ul->move_UE(ul->slices, ue_id, idx); + return 1; } -int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { +int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) { if (!mac_is_present(mod_id)) return 0; void *params = NULL; switch (s->params_case) { @@ -3133,7 +3135,7 @@ int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { char *l = s->label ? strdup(s->label) : NULL; void *algo = &dl->dl_algo; // default scheduler if (s->scheduler) { - algo = dlsym(NULL, s->scheduler); + algo = dlsym(object, s->scheduler); if (!algo) { free(params); LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); @@ -3193,7 +3195,7 @@ int flexran_get_num_dl_slices(mid_t mod_id) { return RC.mac[mod_id]->pre_processor_dl.slices->num; } -int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { +int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) { if (!mac_is_present(mod_id)) return -1; void *params = NULL; switch (s->params_case) { @@ -3210,7 +3212,7 @@ int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { char *l = s->label ? strdup(s->label) : NULL; void *algo = &ul->ul_algo; // default scheduler if (s->scheduler) { - algo = dlsym(NULL, s->scheduler); + algo = dlsym(object, s->scheduler); if (!algo) { free(params); LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); @@ -3276,9 +3278,9 @@ char *flexran_get_dl_scheduler_name(mid_t mod_id) { return RC.mac[mod_id]->pre_processor_dl.dl_algo.name; } -int flexran_set_dl_scheduler(mid_t mod_id, char *sched) { +int flexran_set_dl_scheduler(mid_t mod_id, char *sched, void *object) { if (!mac_is_present(mod_id)) return -1; - void *d = dlsym(NULL, sched); + void *d = dlsym(object, sched); if (!d) return -2; pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl; dl_pp->dl_algo.unset(&dl_pp->dl_algo.data); @@ -3292,9 +3294,9 @@ char *flexran_get_ul_scheduler_name(mid_t mod_id) { return RC.mac[mod_id]->pre_processor_ul.ul_algo.name; } -int flexran_set_ul_scheduler(mid_t mod_id, char *sched) { +int flexran_set_ul_scheduler(mid_t mod_id, char *sched, void *object) { if (!mac_is_present(mod_id)) return -1; - void *d = dlsym(NULL, sched); + void *d = dlsym(object, sched); if (!d) return -2; pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul; ul_pp->ul_algo.unset(&ul_pp->ul_algo.data); @@ -3463,7 +3465,7 @@ int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { if (!rrc_is_present(mod_id)) return -2; /* Reconstruct S1AP_REGISTER_ENB_REQ */ - MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, S1AP_REGISTER_ENB_REQ); + MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, S1AP_REGISTER_ENB_REQ); RCconfig_S1(m, mod_id); const int CC_id = 0; @@ -3489,22 +3491,22 @@ int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num; for (int i = 0; i < mme->broadcast_plmn_num; ++i) S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i]; + S1AP_REGISTER_ENB_REQ(m).mme_port[n] = mme->mme_port; S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; } if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS) return -1; - for (int i = 0; i < n_mme; ++i) { - const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; - strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]); - S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1; - S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0; - S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn; - for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i) - S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i; - S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; - } + const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]); + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1; + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0; + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn; + for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i) + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i; + S1AP_REGISTER_ENB_REQ(m).mme_port[n] = S1AP_PORT_NUMBER; + S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); @@ -3523,7 +3525,7 @@ int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { if (!mme) return -2; - MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SCTP_CLOSE_ASSOCIATION); + MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, SCTP_CLOSE_ASSOCIATION); SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id; itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 2d8a86f7d0..79115b0a16 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -669,15 +669,16 @@ int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo); /* Get the DL slice ID for a UE */ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); /* Set the DL slice for a UE */ -void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); +int flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); /* Get the UL slice ID for a UE */ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); /* Set the UL slice for a UE */ -void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); +int flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); -/* Create slice in DL, returns the new slice index */ -int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s); +/* Create slice in DL, returns the new slice index, object can be shared + * library for the scheduler or NULL */ +int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object); /* Remove slice in DL, returns new number of slices or -1 on error */ int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s); @@ -691,8 +692,9 @@ void flexran_get_dl_slice(mid_t mod_id, /* Get the number of slices in DL */ int flexran_get_num_dl_slices(mid_t mod_id); -/* Create slice in UL, returns the new slice index */ -int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s); +/* Create slice in UL, returns the new slice index, object can be shared library + * for the scheduler or NULL */ +int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object); /* Remove slice in UL */ int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s); @@ -708,14 +710,14 @@ int flexran_get_num_ul_slices(mid_t mod_id); /* Get the name of/Set the DL scheduling algorithm. If slicing is active, this * corresponds to the default algorithm for slices, otherwise the currently - * used one. */ + * used one. object is a shared object in which to find the scheduler */ char *flexran_get_dl_scheduler_name(mid_t mod_id); -int flexran_set_dl_scheduler(mid_t mod_id, char *sched); +int flexran_set_dl_scheduler(mid_t mod_id, char *sched, void *object); /* Get the name of/Set the UL scheduler algorithm. Same applies as for the DL - * case */ + * case. object is a shared object in which to find the scheduler */ char *flexran_get_ul_scheduler_name(mid_t mod_id); -int flexran_set_ul_scheduler(mid_t mod_id, char *sched); +int flexran_set_ul_scheduler(mid_t mod_id, char *sched, void *object); /************************** S1AP **************************/ /* Get the number of MMEs to be connected */ diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index ffbac39983..3a613ca8e5 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -58,6 +58,11 @@ struct timesync { int timer_num; flexran_agent_timer_element_t *timer[MAX_NUM_TIMERS]; + + int add_num; + flexran_agent_timer_element_t *add_list[MAX_NUM_TIMERS]; + int remove_num; + int remove_list[MAX_NUM_TIMERS]; pthread_mutex_t mutex_timer; int exit; @@ -76,8 +81,12 @@ err_code_t flexran_agent_timer_init(mid_t mod_id) { sync->current = 0; sync->next = 0; sync->timer_num = 0; - for (int i = 0; i < MAX_NUM_TIMERS; ++i) + sync->add_num = 0; + sync->remove_num = 0; + for (int i = 0; i < MAX_NUM_TIMERS; ++i) { sync->timer[i] = NULL; + sync->add_list[i] = NULL; + } pthread_mutex_init(&sync->mutex_timer, NULL); sync->exit = 0; @@ -170,12 +179,19 @@ void *flexran_agent_timer_thread(void *args) { break; pthread_mutex_lock(&sync->mutex_timer); - sync->current++; - - if (sync->current < sync->next) { - pthread_mutex_unlock(&sync->mutex_timer); - continue; + for (int i = 0; i < sync->add_num; ++i) { + sync->timer[sync->timer_num] = sync->add_list[i]; + sync->timer_num++; } + sync->add_num = 0; + for (int i = 0; i < sync->remove_num; ++i) + flexran_agent_timer_remove_internal(sync, sync->remove_list[i]); + sync->remove_num = 0; + pthread_mutex_unlock(&sync->mutex_timer); + + sync->current++; + if (sync->current < sync->next) + continue; for (int i = 0; i < sync->timer_num; ++i) { flexran_agent_timer_element_t *t = sync->timer[i]; @@ -186,7 +202,6 @@ void *flexran_agent_timer_thread(void *args) { if (sync->next == sync->current || t->next < sync->next) sync->next = t->next; } - pthread_mutex_unlock(&sync->mutex_timer); } LOG_W(FLEXRAN_AGENT, "terminated timer thread\n"); return NULL; @@ -230,45 +245,35 @@ err_code_t flexran_agent_create_timer(mid_t mod_id, struct timesync *sync = ×ync[mod_id]; pthread_mutex_lock(&sync->mutex_timer); - if (sync->timer_num >= MAX_NUM_TIMERS) { + if (sync->timer_num + sync->add_num >= MAX_NUM_TIMERS) { pthread_mutex_unlock(&sync->mutex_timer); LOG_E(FLEXRAN_AGENT, "maximum number of timers (%d) reached while adding timer %d\n", - sync->timer_num, xid); + sync->timer_num + sync->add_num, xid); free(t); return TIMER_SETUP_FAILED; } /* TODO check that xid does not exist? */ - t->next = sync->current + 1; + t->next = sync->current + sf; if (sync->next <= sync->current || t->next < sync->next) sync->next = t->next; - sync->timer[sync->timer_num] = t; - sync->timer_num++; - pthread_mutex_unlock(&sync->mutex_timer); - LOG_D(FLEXRAN_AGENT, "added new timer xid %d for agent %d\n", xid, mod_id); - return 0; -} - -err_code_t flexran_agent_destroy_timers(mid_t mod_id) { - struct timesync *sync = ×ync[mod_id]; - pthread_mutex_lock(&sync->mutex_timer); - for (int i = sync->timer_num - 1; i < 0; --i) { - flexran_agent_timer_remove_internal(sync, i); - } + sync->add_list[sync->add_num] = t; + sync->add_num++; pthread_mutex_unlock(&sync->mutex_timer); + LOG_I(FLEXRAN_AGENT, "added new timer xid %d for agent %d\n", xid, mod_id); return 0; } err_code_t flexran_agent_destroy_timer(mid_t mod_id, xid_t xid) { struct timesync *sync = ×ync[mod_id]; - pthread_mutex_lock(&sync->mutex_timer); for (int i = 0; i < sync->timer_num; ++i) { if (sync->timer[i]->xid == xid) { - flexran_agent_timer_remove_internal(sync, i); + pthread_mutex_lock(&sync->mutex_timer); + sync->remove_list[sync->remove_num] = i; + sync->remove_num++; pthread_mutex_unlock(&sync->mutex_timer); return 0; } } - pthread_mutex_unlock(&sync->mutex_timer); LOG_E(FLEXRAN_AGENT, "could not find timer %d\n", xid); return TIMER_ELEMENT_NOT_FOUND; } @@ -277,7 +282,8 @@ err_code_t flexran_agent_destroy_timer(mid_t mod_id, xid_t xid) { void flexran_agent_timer_remove_internal(struct timesync *sync, int index) { LOG_I(FLEXRAN_AGENT, "remove timer xid %d (index %d) for agent %d\n", sync->timer[index]->xid, index, sync->timer[index]->mod_id); - flexran_agent_destroy_flexran_message(sync->timer[index]->msg); + if (sync->timer[index]->msg) + flexran_agent_destroy_flexran_message(sync->timer[index]->msg); free(sync->timer[index]); for (int i = index + 1; i < sync->timer_num; ++i) sync->timer[i - 1] = sync->timer[i]; diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index b1cf8df51f..c61f2543a3 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -61,9 +61,6 @@ err_code_t flexran_agent_create_timer(mid_t mod_id, flexran_agent_timer_callback_t cb, Protocol__FlexranMessage *msg); -/* Destroy all existing timers */ -err_code_t flexran_agent_destroy_timers(mid_t mod_id); - /* Destroy the timer for task with id xid */ err_code_t flexran_agent_destroy_timer(mid_t mod_id, xid_t xid); diff --git a/openair2/ENB_APP/flexran_apps/imsi.c b/openair2/ENB_APP/flexran_apps/imsi.c new file mode 100644 index 0000000000..6f75033f38 --- /dev/null +++ b/openair2/ENB_APP/flexran_apps/imsi.c @@ -0,0 +1,245 @@ +/* + * 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 imsi.c + * \brief flexran IMSI UE-slice association app + * \author Robert Schmidt, Firas Abdeljelil + * \date 2020 + * \version 0.1 + */ + +#include +#include +#include +#include "flexran_agent_common.h" +#include "flexran_agent_async.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_net_comm.h" +#include "flexran_agent_ran_api.h" +#include "flexran_agent_phy.h" +#include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" +#include "flexran_agent_s1ap.h" +#include "flexran_agent_app.h" +#include "common/utils/LOG/log.h" +#include "assertions.h" +#include "queue.h" +typedef struct Map_regex_slice slist_data_t; +struct Map_regex_slice { + char regex_[30] ; + int slice_dl; + int slice_ul; + regex_t regex; + SLIST_ENTRY (Map_regex_slice) entries; +}; +bool reconfig = false; +int ue[MAX_MOBILES_PER_ENB]={ [0 ... MAX_MOBILES_PER_ENB - 1] = -1 }; + +SLIST_HEAD(slisthead, Map_regex_slice) head; + +int dump_list(void) { + int len = 1; + slist_data_t *datap = NULL; + SLIST_FOREACH(datap, &head, entries) { + LOG_W(FLEXRAN_AGENT, "%d: regex %s DL %d UL %d\n", len++, datap->regex_, + datap->slice_dl, datap->slice_ul); + } + return len; +} + +void add(char *regex, int dl, int ul) { + slist_data_t *datap = malloc(sizeof(slist_data_t)); + if (!datap) { + LOG_E(FLEXRAN_AGENT, "cannot allocate memory for slist_data_t\n"); + return; + } + strcpy(datap->regex_, regex); + datap->slice_dl = dl; + datap->slice_ul = ul; + regcomp(&datap->regex, datap->regex_, 0); + SLIST_INSERT_HEAD(&head, datap, entries); + if (ul==-1) + LOG_I(FLEXRAN_AGENT, "added new element to list: regex %s slice DL %d\n" ,regex, dl); + else if (dl==-1) + LOG_I(FLEXRAN_AGENT, "added new element to list: regex %s slice UL %d\n" ,regex, ul); + else + LOG_I(FLEXRAN_AGENT, "added new element to list: regex %s slice DL %d UL %d\n", + regex, dl, ul); +} +void remove_(char *regex) { + slist_data_t *datap = NULL; + SLIST_FOREACH(datap, &head, entries) { + if (strcmp(datap->regex_, regex) == 0) { + SLIST_REMOVE(&head, datap, Map_regex_slice, entries); + if (datap->slice_dl==-1) + LOG_I(FLEXRAN_AGENT, "removed element from list: regex %s slice UL %d\n",datap->regex_, datap->slice_ul); + else if (datap->slice_ul==-1) + LOG_I(FLEXRAN_AGENT, "removed element from list: regex %s slice DL %d\n",datap->regex_, datap->slice_dl); + else + LOG_I(FLEXRAN_AGENT, "removed element from list: regex %s slice DL %d UL %d\n", + datap->regex_, datap->slice_dl, datap->slice_ul); + regfree(&datap->regex); + free(datap); + return; + } + } + LOG_E(FLEXRAN_AGENT, "no regex %s found in list\n", regex); +} + +Protocol__FlexranMessage *matching_tick( + mid_t mod_id, + const Protocol__FlexranMessage *msg) { + const int num = flexran_get_mac_num_ues(mod_id); + for (int i = 0; i < num; i++) { + int ue_id = flexran_get_mac_ue_id(mod_id, i); + if (ue[ue_id] >= 0 && !reconfig) + continue; + rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); + uint64_t imsi = flexran_get_ue_imsi(mod_id, rnti); + char snum[20]; + sprintf(snum, "%" PRIu64, imsi); + slist_data_t *datap = NULL; + SLIST_FOREACH(datap, &head, entries) { + if (regexec(&datap->regex, snum, 0, NULL, 0) == 0) { + + int dl = datap->slice_dl; + if (dl >= 0 && dl != flexran_get_ue_dl_slice_id(mod_id, ue_id)) { + int ra = flexran_set_ue_dl_slice_id(mod_id, ue_id, dl); + if (ra) + LOG_I(FLEXRAN_AGENT, + "RNTI %04x/IMSI %s in the slice_dl %d\n", + rnti, + snum, + dl); + else + LOG_W(FLEXRAN_AGENT, "No such DL slice %d\n", dl); + } + + int ul = datap->slice_ul; + if (ul >= 0 && ul != flexran_get_ue_ul_slice_id(mod_id, ue_id)) { + int rb = flexran_set_ue_ul_slice_id(mod_id, ue_id, ul); + if (rb) + LOG_I(FLEXRAN_AGENT, + "RNTI %04x/IMSI %s in the slice_ul %d\n", + rnti, + snum, + ul); + else + LOG_W(FLEXRAN_AGENT, "No such DL slice %d\n", dl); + } + } + } + ue[ue_id] = ue_id; + } + reconfig = false; + return NULL; +} +void add_param(Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, int n_p) { + char s[30]; + reconfig = true; + bool supp=false; + bool sl_E=false; + int dl=-1; + int ul=-1; + slist_data_t *datap = NULL; + for (int i = 0; i < n_p; ++i) { + switch (p[i]->value->param_case) { + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM__NOT_SET: + LOG_I(FLEXRAN_AGENT, " param %s is not set\n", p[i]->key); + break; + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_INTEGER: + if( strcmp(p[i]->key, "slice_dl")==0) + dl= p[i]->value->integer; + else + ul= p[i]->value->integer; + sl_E=true; + break; + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_STR: + strcpy(s,p[i]->value->str); + break; + default: + LOG_W(FLEXRAN_AGENT, " type of param %s is unknown\n", p[i]->key); + break; + }; + } + if (!SLIST_EMPTY(&head)){ + SLIST_FOREACH(datap, &head, entries) { + if (strcmp(datap->regex_, s) == 0) { + if (datap->slice_dl!=dl || datap->slice_ul!=ul) + supp=true; + } + } + } + if (sl_E==false) + remove_(s); + else { + if (supp==true) + remove_(s); + add(s,dl,ul); + } + /* re-verify all UEs again */ + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + ue[i] = -1; +} +/* imsi_start: entry point for imsi app. Installs a callback using the timer + * API to have function imsi_tick() called every 5s */ +#define TIMER 32 +int imsi_start(mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, + int n_p) +{ + LOG_W(FLEXRAN_AGENT, "%s(): enable IMSI app timer\n", __func__); + flexran_agent_create_timer(mod_id, + 500, + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, + TIMER, + matching_tick, + NULL); + SLIST_INIT(&head); + return 0; +} + +int imsi_reconfig(mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, + int n_p) +{ + add_param(p, n_p); + return 0; +} + +/* stop function: cleans up before app can be unloaded. Here: stop the timer */ +int imsi_stop(mid_t mod_id) { + LOG_W(FLEXRAN_AGENT, "%s(): disable IMSI app timer\n", __func__); + flexran_agent_destroy_timer(mod_id, TIMER); + + return 0; +} + +/* app definition. visibility should be set to default so this symbol is + * reachable from outside */ +flexran_agent_app_t __attribute__ ((visibility ("default"))) app = { + .start = imsi_start, + .reconfig = imsi_reconfig, + .stop = imsi_stop +}; diff --git a/openair2/ENB_APP/flexran_apps/sample.c b/openair2/ENB_APP/flexran_apps/sample.c new file mode 100644 index 0000000000..65be2a43df --- /dev/null +++ b/openair2/ENB_APP/flexran_apps/sample.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 + */ + +/*! \file sample.c + * \brief flexran sample app + * \author Robert Schmidt + * \date 2020 + * \version 0.1 + */ + +#include "flexran_agent_common.h" +#include "flexran_agent_async.h" +#include "flexran_agent_extern.h" +#include "flexran_agent_timer.h" +#include "flexran_agent_defs.h" +#include "flexran_agent_net_comm.h" +#include "flexran_agent_ran_api.h" +#include "flexran_agent_phy.h" +#include "flexran_agent_mac.h" +#include "flexran_agent_rrc.h" +#include "flexran_agent_pdcp.h" +#include "flexran_agent_s1ap.h" +#include "flexran_agent_app.h" +#include "common/utils/LOG/log.h" +#include "assertions.h" + +/* callback to be called for event: shows exemplary variable use and use of RAN + * API */ +int tick; +Protocol__FlexranMessage *sample_tick( + mid_t mod_id, + const Protocol__FlexranMessage *msg) { + tick++; + const int num = flexran_get_mac_num_ues(mod_id); + LOG_I(FLEXRAN_AGENT, "%s(): tick %d number UEs %d\n", __func__, tick, num); + return NULL; +} + +void print_param(Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, int n_p) { + LOG_I(FLEXRAN_AGENT, "%s(): received %d parameters\n", __func__, n_p); + for (int i = 0; i < n_p; ++i) { + switch (p[i]->value->param_case) { + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM__NOT_SET: + LOG_I(FLEXRAN_AGENT, " param %s is not set\n", p[i]->key); + break; + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_INTEGER: + LOG_I(FLEXRAN_AGENT, " param %s is %d\n", p[i]->key, p[i]->value->integer); + break; + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_FLOATING: + LOG_I(FLEXRAN_AGENT, " param %s is %f\n", p[i]->key, p[i]->value->floating); + break; + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_BOOLEAN: + LOG_I(FLEXRAN_AGENT, " param %s is %s\n", p[i]->key, p[i]->value->boolean ? "true" : "false"); + break; + case PROTOCOL__FLEX_AGENT_RECONFIGURATION_PARAM__PARAM_STR: + LOG_I(FLEXRAN_AGENT, " param %s is %s\n", p[i]->key, p[i]->value->str); + break; + default: + LOG_W(FLEXRAN_AGENT, " type of param %s is unknown\n", p[i]->key); + break; + }; + } +} + +/* sa_start: entry point for sample app. Installs a callback using the timer + * API to have function sample_tick() called every 5s */ +#define TIMER 22 +int sa_start(mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, + int n_p) { + LOG_W(FLEXRAN_AGENT, "%s(): enable sample app timer\n", __func__); + flexran_agent_create_timer(mod_id, + 5000, + FLEXRAN_AGENT_TIMER_TYPE_PERIODIC, + TIMER, + sample_tick, + NULL); + print_param(p, n_p); + return 0; +} + +int sa_reconfig(mid_t mod_id, + Protocol__FlexAgentReconfigurationSubsystem__ParamsEntry **p, + int n_p) +{ + print_param(p, n_p); + return 0; +} + +/* stop function: cleans up before app can be unloaded. Here: stop the timer */ +int sa_stop(mid_t mod_id) { + LOG_W(FLEXRAN_AGENT, "%s(): disable sample app timer\n", __func__); + flexran_agent_destroy_timer(mod_id, TIMER); + return 0; +} + +/* app definition. visibility should be set to default so this symbol is + * reachable from outside */ +flexran_agent_app_t __attribute__ ((visibility ("default"))) app = { + .start = sa_start, + .reconfig = sa_reconfig, + .stop = sa_stop +}; diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index 48c5c2de11..01cd4aa9e0 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -102,7 +102,7 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message(TASK_RRC_ENB, F1AP_SETUP_REQ); + message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_SETUP_REQ); /* assoc_id */ F1AP_SETUP_REQ(message_p).assoc_id = assoc_id; diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 9bd04cc5e8..306a1fe14b 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -116,7 +116,7 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_ProtocolIE_ID_id_RRCContainer, true); // create an ITTI message and copy SDU - message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND); + message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); ccch_sdu_len = ie->value.choice.RRCContainer.size; memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, @@ -197,7 +197,7 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, ie->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_CU_UE_F1AP_ID; ie->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(&f1ap_cu_inst[instance], f1ap_dl_rrc->rnti); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - LOG_I(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %d)\n", + LOG_I(F1AP, "Setting GNB_CU_UE_F1AP_ID %llu associated with UE RNTI %x (instance %ld)\n", (unsigned long long int)ie->value.choice.GNB_CU_UE_F1AP_ID, f1ap_dl_rrc->rnti, instance); @@ -350,7 +350,7 @@ int CU_handle_UL_RRC_MESSAGE_TRANSFER(instance_t instance, // create an ITTI message and copy SDU /* - message_p = itti_alloc_new_message (TASK_CU_F1, RRC_DCCH_DATA_IND); + message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_DCCH_DATA_IND); RRC_DCCH_DATA_IND (message_p).sdu_p = malloc(ie->value.choice.RRCContainer.size); diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 9ab84e6bc9..d2f4c3a56b 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -52,7 +52,7 @@ void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat DevAssert(sctp_new_association_resp != NULL); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -78,7 +78,7 @@ void cu_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat .remote_port = RC.rrc[instance]->eth_params_s.remote_portd }; AssertFatal(proto_agent_start(instance, ¶ms) == 0, - "could not start PROTO_AGENT for F1U on instance %d!\n", instance); + "could not start PROTO_AGENT for F1U on instance %ld!\n", instance); } void cu_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { @@ -101,7 +101,7 @@ void cu_task_send_sctp_init_req(instance_t enb_id) { LOG_I(F1AP, "F1AP_CU_SCTP_REQ(create socket)\n"); MessageDef *message_p = NULL; - message_p = itti_alloc_new_message (TASK_CU_F1, SCTP_INIT_MSG); + message_p = itti_alloc_new_message (TASK_CU_F1, 0, SCTP_INIT_MSG); message_p->ittiMsg.sctp_init.port = F1AP_PORT_NUMBER; message_p->ittiMsg.sctp_init.ppid = F1AP_SCTP_PPID; message_p->ittiMsg.sctp_init.ipv4 = 1; @@ -138,43 +138,43 @@ void *F1AP_CU_task(void *arg) { switch (ITTI_MSG_ID(received_msg)) { case SCTP_NEW_ASSOCIATION_IND: - LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %d\n", - ITTI_MESSAGE_GET_INSTANCE(received_msg)); - cu_task_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_IND for instance %ld\n", + ITTI_MSG_DESTINATION_INSTANCE(received_msg)); + cu_task_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind); break; case SCTP_NEW_ASSOCIATION_RESP: - LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %d\n", - ITTI_MESSAGE_GET_INSTANCE(received_msg)); - cu_task_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + LOG_I(F1AP, "CU Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n", + ITTI_MSG_DESTINATION_INSTANCE(received_msg)); + cu_task_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_DATA_IND: - LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %d\n", - ITTI_MESSAGE_GET_INSTANCE(received_msg)); - cu_task_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + LOG_I(F1AP, "CU Task Received SCTP_DATA_IND for Instance %ld\n", + ITTI_MSG_DESTINATION_INSTANCE(received_msg)); + cu_task_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; case F1AP_SETUP_RESP: // from rrc LOG_I(F1AP, "CU Task Received F1AP_SETUP_RESP\n"); - // CU_send_f1setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + // CU_send_f1setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &F1AP_SETUP_RESP(received_msg)); - CU_send_F1_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + CU_send_F1_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_SETUP_RESP(received_msg)); break; case F1AP_DL_RRC_MESSAGE: // from rrc LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n"); - CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), + CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_DL_RRC_MESSAGE(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n"); - CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MESSAGE_GET_INSTANCE(received_msg), + CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); break; diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 341c050f55..86b5b1cb77 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -444,7 +444,7 @@ int DU_handle_F1_SETUP_RESPONSE(instance_t instance, int num_cells_to_activate = 0; F1AP_Cells_to_be_Activated_List_Item_t *cell; - MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, F1AP_SETUP_RESP); + MessageDef *msg_p = itti_alloc_new_message (TASK_DU_F1, 0, F1AP_SETUP_RESP); LOG_D(F1AP, "F1AP: F1Setup-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 6953588818..ee096337dd 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -143,7 +143,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, // BK: need check // create an ITTI message and copy SDU - // message_p = itti_alloc_new_message (TASK_CU_F1, RRC_MAC_CCCH_DATA_IND); + // message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); // memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); rrc_dl_sdu_len = ie->value.choice.RRCContainer.size; // memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, @@ -402,7 +402,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, MessageDef *message_p = NULL; /* Send DRX configuration to MAC task to configure timers of local UE context */ - message_p = itti_alloc_new_message(TASK_DU_F1, RRC_MAC_DRX_CONFIG_REQ); + message_p = itti_alloc_new_message(TASK_DU_F1, 0, RRC_MAC_DRX_CONFIG_REQ); RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = ctxt.rnti; RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; itti_send_msg_to_task(TASK_MAC_ENB, ctxt.module_id, message_p); @@ -599,7 +599,7 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, uint32_t len; - LOG_I(F1AP, "[DU %d] %s: size %d UE RNTI %x in SRB %d\n", + LOG_I(F1AP, "[DU %ld] %s: size %d UE RNTI %x in SRB %d\n", instance, __func__, msg->rrc_container_length, rnti, msg->srb_id); //LOG_I(F1AP, "%s() RRCContainer size %d: ", __func__, msg->rrc_container_length); diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index 566391ac7a..b66141250b 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -50,7 +50,7 @@ void du_task_send_sctp_association_req(instance_t instance, f1ap_setup_req_t *f1 MessageDef *message_p = NULL; sctp_new_association_req_t *sctp_new_association_req_p = NULL; - message_p = itti_alloc_new_message(TASK_DU_F1, SCTP_NEW_ASSOCIATION_REQ); + message_p = itti_alloc_new_message(TASK_DU_F1, 0, SCTP_NEW_ASSOCIATION_REQ); sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; sctp_new_association_req_p->ulp_cnx_id = instance; @@ -86,7 +86,7 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat DevAssert(sctp_new_association_resp != NULL); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + LOG_W(F1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -109,7 +109,7 @@ void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_associat .remote_port = RC.mac[instance]->eth_params_n.remote_portd }; AssertFatal(proto_agent_start(instance, ¶ms) == 0, - "could not start PROTO_AGENT for F1U on instance %d!\n", instance); + "could not start PROTO_AGENT for F1U on instance %ld!\n", instance); DU_send_F1_SETUP_REQUEST(instance); } @@ -156,7 +156,7 @@ void *F1AP_DU_task(void *arg) { // 2. store the message in f1ap context, that is also stored in RC // 2. send a sctp_association req LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); - du_task_send_sctp_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + du_task_send_sctp_association_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_SETUP_REQ(received_msg)); break; @@ -164,26 +164,26 @@ void *F1AP_DU_task(void *arg) { // 1. store the respon // 2. send the f1setup_req LOG_I(F1AP, "DU Task Received SCTP_NEW_ASSOCIATION_RESP\n"); - du_task_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + du_task_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_DATA_IND: // ex: any F1 incoming message for DU ends here LOG_I(F1AP, "DU Task Received SCTP_DATA_IND\n"); - du_task_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + du_task_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; case F1AP_UL_RRC_MESSAGE: // to rrc LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); - DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg), + DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_UL_RRC_MESSAGE(received_msg)); break; case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n"); - DU_send_UE_CONTEXT_RELEASE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + DU_send_UE_CONTEXT_RELEASE_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_UE_CONTEXT_RELEASE_REQ(received_msg)); break; diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index bae59a509e..841c77eef5 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -59,7 +59,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, F1AP_UEContextSetupRequestIEs_t *ie; int i; DevAssert(pdu); - msg_p = itti_alloc_new_message(TASK_DU_F1, F1AP_UE_CONTEXT_SETUP_REQ); + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_SETUP_REQ); f1ap_ue_context_setup_req_t *f1ap_ue_context_setup_req; f1ap_ue_context_setup_req = &F1AP_UE_CONTEXT_SETUP_REQ(msg_p); container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest; diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index 12aba18a9d..45f76d3dab 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -119,7 +119,7 @@ int f1ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream, } /* Calling the right handler */ - LOG_I(F1AP, "Calling handler with instance %d\n",instance); + LOG_I(F1AP, "Calling handler with instance %ld\n",instance); ret = (*f1ap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index fa8951536a..443357a45e 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -28,7 +28,7 @@ void cu_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_CU_F1, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_CU_F1, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -46,7 +46,7 @@ void du_f1ap_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_DU_F1, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_DU_F1, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -64,7 +64,7 @@ void f1ap_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index a5a808c281..67be560778 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -46,6 +46,7 @@ #define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" #define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" #define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" +#define CONFIG_STRING_L1_PUSCH_PROC_THREADS "pusch_proc_threads" /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* L1 configuration parameters */ @@ -61,6 +62,7 @@ {CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0} \ } #define L1_CC_IDX 0 #define L1_TRANSPORT_N_PREFERENCE_IDX 1 @@ -71,6 +73,7 @@ #define L1_REMOTE_N_PORTC_IDX 6 #define L1_LOCAL_N_PORTD_IDX 7 #define L1_REMOTE_N_PORTD_IDX 8 +#define L1_PUSCH_PROC_THREADS 9 /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 231aeb34f4..1f1d076e9d 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_PDCCH_CONFIGSIB1 "pdcch_ConfigSIB1" #define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon" #define GNB_CONFIG_STRING_PHYSCELLID "physCellId" #define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset" @@ -210,6 +211,21 @@ #define CARRIERBANDWIDTH_OKVALUES {11,18,24,25,31,32,38,51,52,65,66,78,79,93,106,107,121,132,133,135,160,162,189,216,217,245,264,270,273} +/*--------------------------------------------------------------------------------------------------------------------*/ +/* pdcch_ConfigSIB1 parameters */ +/*--------------------------------------------------------------------------------------------------------------------*/ +#define CONTROL_RESOURCE_SET_ZERO "controlResourceSetZero" +#define SEARCH_SPACE_ZERO "searchSpaceZero" + +#define PDCCH_CONFIGSIB1PARAMS_DESC(pdcch_ConfigSIB1) { \ +{CONTROL_RESOURCE_SET_ZERO, NULL, 0, i64ptr:&pdcch_ConfigSIB1->controlResourceSetZero, defintval:0, TYPE_INT64, 0}, \ +{SEARCH_SPACE_ZERO, NULL, 0, i64ptr:&pdcch_ConfigSIB1->searchSpaceZero, defintval:0, TYPE_INT64, 0} \ +} + +#define CONTROL_RESOURCE_SET_ZERO_IDX 0 +#define SEARCH_SPACE_ZERO_IDX 1 +/*--------------------------------------------------------------------------------------------------------------------*/ + /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* Serving Cell Config Common configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 9bdd709262..77e4564632 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -39,7 +39,7 @@ #include "x2ap_eNB.h" #include "intertask_interface.h" -#include "s1ap_eNB.h" +#include "ngap_gNB.h" #include "sctp_eNB_task.h" #include "gtpv1u_eNB_task.h" #include "PHY/INIT/phy_init.h" @@ -56,7 +56,7 @@ static void configure_nr_rrc(uint32_t gnb_id) MessageDef *msg_p = NULL; // int CC_id; - msg_p = itti_alloc_new_message (TASK_GNB_APP, NRRRC_CONFIGURATION_REQ); + msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ); if (RC.nrrrc[gnb_id]) { RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]); @@ -75,26 +75,29 @@ static void configure_nr_rrc(uint32_t gnb_id) static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties) { uint32_t gnb_id; - //MessageDef *msg_p; + MessageDef *msg_p; uint32_t register_gnb_pending = 0; for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { { - //s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse + if(NGAP_CONF_MODE){ + ngap_register_gnb_req_t *ngap_register_gNB; //Type Temporarily reuse + + // note: there is an implicit relationship between the data structure and the message name + msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); //Message Temporarily reuse - // note: there is an implicit relationship between the data structure and the message name - /*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse + RCconfig_NR_NG(msg_p, gnb_id); + + ngap_register_gNB = &NGAP_REGISTER_GNB_REQ(msg_p); //Message Temporarily reuse - RCconfig_NR_S1(msg_p, gnb_id);*/ + LOG_I(GNB_APP,"default drx %d\n",ngap_register_gNB->default_drx); + + itti_send_msg_to_task (TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); + } if (gnb_id == 0) RCconfig_nr_gtpu(); - /*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse - LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/ - - LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id)); - - //itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); + LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id)); register_gnb_pending++; } @@ -112,7 +115,7 @@ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) { { - msg_p = itti_alloc_new_message (TASK_GNB_APP, X2AP_REGISTER_ENB_REQ); + msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, X2AP_REGISTER_ENB_REQ); LOG_I(X2AP, "GNB_ID: %d \n", gnb_id); RCconfig_NR_X2(msg_p, gnb_id); itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); @@ -173,13 +176,13 @@ void *gNB_app_task(void *args_p) __attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end); } - if (EPC_MODE_ENABLED) { + if (AMF_MODE_ENABLED) { /* Try to register each gNB */ //registered_gnb = 0; __attribute__((unused)) uint32_t register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p); } else { /* Start L2L1 task */ - msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE); + msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, INITIALIZE_MESSAGE); itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p); } @@ -188,7 +191,7 @@ void *gNB_app_task(void *args_p) itti_receive_msg (TASK_GNB_APP, &msg_p); msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -201,16 +204,16 @@ void *gNB_app_task(void *args_p) break; -/* - case S1AP_REGISTER_ENB_CNF: - LOG_I(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name, - S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); + case NGAP_REGISTER_GNB_CNF: + LOG_I(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name, + NGAP_REGISTER_GNB_CNF(msg_p).nb_amf); +/* DevAssert(register_gnb_pending > 0); register_gnb_pending--; - // Check if at least gNB is registered with one MME - if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) { + // Check if at least gNB is registered with one AMF + if (NGAP_REGISTER_GNB_CNF(msg_p).nb_amf > 0) { registered_gnb++; } @@ -220,13 +223,13 @@ void *gNB_app_task(void *args_p) // If all gNB are registered, start L2L1 task MessageDef *msg_init_p; - msg_init_p = itti_alloc_new_message (TASK_GNB_APP, INITIALIZE_MESSAGE); + msg_init_p = itti_alloc_new_message (TASK_GNB_APP, 0, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); } else { uint32_t not_associated = gnb_nb - registered_gnb; - LOG_W(GNB_APP, " %d gNB %s not associated with a MME, retrying registration in %d seconds ...\n", + LOG_W(GNB_APP, " %d gNB %s not associated with a AMF, retrying registration in %d seconds ...\n", not_associated, not_associated > 1 ? "are" : "is", GNB_REGISTER_RETRY_DELAY); // Restart the gNB registration process in GNB_REGISTER_RETRY_DELAY seconds @@ -241,12 +244,12 @@ void *gNB_app_task(void *args_p) } } } - - break; */ - case S1AP_DEREGISTERED_ENB_IND: - LOG_W(GNB_APP, "[gNB %d] Received %s: associated MME %d\n", instance, msg_name, - S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme); + break; + + case NGAP_DEREGISTERED_GNB_IND: + LOG_W(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name, + NGAP_DEREGISTERED_GNB_IND(msg_p).nb_amf); /* TODO handle recovering of registration */ break; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 8c8e78bbd0..0c056d27b6 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -34,10 +34,12 @@ #include "common/utils/LOG/log_extern.h" #include "assertions.h" #include "gnb_config.h" +#include "gnb_paramdef.h" #include "UTIL/OTG/otg.h" #include "UTIL/OTG/otg_externs.h" #include "intertask_interface.h" #include "s1ap_eNB.h" +#include "ngap_gNB.h" #include "sctp_eNB_task.h" #include "sctp_default_values.h" // #include "SystemInformationBlockType2.h" @@ -49,7 +51,8 @@ #include "nfapi_vnf.h" #include "nfapi_pnf.h" -#include "L1_paramdef.h" +//#include "L1_paramdef.h" +#include "L1_nr_paramdef.h" #include "MACRLC_paramdef.h" #include "common/config/config_userapi.h" //#include "RRC_config_tools.h" @@ -153,7 +156,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) { scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_RACH_ConfigCommon_t)); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->present = NR_SetupRelease_RACH_ConfigCommon_PR_setup; 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->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)); @@ -231,8 +234,8 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] |= curr_bit<ssb_PositionsInBurst->choice.mediumBitmap.size = 1; - scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0; + 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] = 0; for (int i=0; i<8; i++) @@ -242,10 +245,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { scc->ssb_PositionsInBurst->choice.longBitmap.bits_unused = 0; scc->ssb_PositionsInBurst->choice.longBitmap.buf = CALLOC(1,8); for (int j=0; j<8; j++) { - scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] = 0; + scc->ssb_PositionsInBurst->choice.longBitmap.buf[j] = 0; curr_bit = (ssbmap>>(j<<3))&(0xff); for (int i=0; i<8; i++) - scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] |= (((curr_bit>>(7-i))&0x01)<ssb_PositionsInBurst->choice.longBitmap.buf[j] |= (((curr_bit>>(7-i))&0x01)<Mod_id = j; } + RC.gNB[j]->pusch_proc_threads = *(L1_ParamList.paramarray[j][L1_PUSCH_PROC_THREADS].uptr); + if(strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { //sf_ahead = 2; // Need 4 subframe gap between RX and TX }else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { @@ -535,7 +540,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { AssertFatal (icarrier.pdcch_ConfigSIB1 = calloc(1,sizeof(NR_PDCCH_ConfigSIB1_t)); + paramdef_t pdcch_ConfigSIB1[] = PDCCH_CONFIGSIB1PARAMS_DESC(rrc->carrier.pdcch_ConfigSIB1); + paramlist_def_t pdcch_ConfigSIB1ParamList = {GNB_CONFIG_STRING_PDCCH_CONFIGSIB1, NULL, 0}; + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); + config_getlist(&pdcch_ConfigSIB1ParamList, NULL, 0, aprefix); + if (pdcch_ConfigSIB1ParamList.numelt > 0) { + sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_PDCCH_CONFIGSIB1, 0); + config_get(pdcch_ConfigSIB1,sizeof(pdcch_ConfigSIB1)/sizeof(paramdef_t),aprefix); + } + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); config_getlist(&SCCsParamList, NULL, 0, aprefix); @@ -672,16 +688,19 @@ int RCconfig_nr_gtpu(void ) { + char* gnb_interface_name_for_NGU = NULL; + char* gnb_ipv4_address_for_NGU = NULL; + uint32_t gnb_port_for_NGU = 0; char* gnb_interface_name_for_S1U = NULL; char* gnb_ipv4_address_for_S1U = NULL; uint32_t gnb_port_for_S1U = 0; char *address = NULL; char *cidr = NULL; char gtpupath[MAX_OPTNAME_SIZE*2 + 8]; - + uint8_t gnb_mode = 0; paramdef_t GNBSParams[] = GNBSPARAMS_DESC; - + paramdef_t NETParams[] = GNBNETPARAMS_DESC; paramdef_t GTPUParams[] = GNBGTPUPARAMS_DESC; LOG_I(GTPU,"Configuring GTPu\n"); @@ -691,34 +710,49 @@ int RCconfig_nr_gtpu(void ) { AssertFatal (num_gnbs >0, "Failed to parse config file no active gNodeBs in %s \n", GNB_CONFIG_STRING_ACTIVE_GNBS); - sprintf(gtpupath,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); - + config_get(GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath); + config_get(NETParams,sizeof(NETParams)/sizeof(paramdef_t),gtpupath); + if (NETParams[0].strptr != NULL) { // SA + LOG_I(GTPU, "SA mode \n"); + cidr = gnb_ipv4_address_for_NGU; + gnb_mode = 0; + } else {// NSA + LOG_I(GTPU, "NSA mode \n"); cidr = gnb_ipv4_address_for_S1U; + gnb_mode = 1; + } + address = strtok(cidr, "/"); - + if (address) { MessageDef *message; - AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,""); - // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); - // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); + if (gnb_mode == 1) { // NSA + AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,""); + // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); + IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); + GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U; + } else {// TODO SA + AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ))!=NULL,""); + IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" ); + LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up); + GTPV1U_GNB_NG_REQ(message).gnb_port_for_NGu_up = gnb_port_for_NGU; + } - IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); - LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); - GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U; itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else - LOG_E(GTPU,"invalid address for S1U\n"); + LOG_E(GTPU,"invalid address for NGU\n"); return 0; } -int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { +int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { int j,k = 0; int gnb_id; @@ -741,7 +775,7 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); /* - if (EPC_MODE_ENABLED) { + if (AMF_MODE_ENABLED) { if (strcasecmp( *(GNBSParams[GNB_ASN1_VERBOSITY_IDX].strptr), GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) { asn_debug = 0; asn1_xer_print = 0; @@ -766,56 +800,61 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt>0) { // Output a list of all gNBs. config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); - if (GNBParamList.numelt > 0) { for (k = 0; k < GNBParamList.numelt; k++) { - if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { - // Calculate a default gNB ID - if (EPC_MODE_ENABLED) { - uint32_t hash; - - hash = s1ap_generate_eNB_id (); - gnb_id = k + (hash & 0xFFFF8); - } else { - gnb_id = k; - } - } else { + if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { + // Calculate a default gNB ID + if (AMF_MODE_ENABLED) { + uint32_t hash; + + hash = ngap_generate_gNB_id (); + gnb_id = k + (hash & 0xFFFFFF8); + } else { + gnb_id = k; + } + } else { gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr); } - // search if in active list - for (j=0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { - if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { + // search if in active list + for (j=0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { + if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC; + paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0}; /* map parameter checking array instances to parameter definition array instances */ checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + checkedparam_t config_check_SNSSAIParams [] = SNSSAIPARAMS_CHECK; for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + for (int J = 0; J < sizeof(SNSSAIParams) / sizeof(paramdef_t); ++J) + SNSSAIParams[J].chkPptr = &(config_check_SNSSAIParams[J]); - paramdef_t S1Params[] = GNBS1PARAMS_DESC; - paramlist_def_t S1ParamList = {GNB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0}; - - paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC; - paramdef_t NETParams[] = GNBNETPARAMS_DESC; - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - - S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = gnb_id; - - if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB; - } else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; - } else { - AssertFatal (0, - "Failed to parse gNB configuration file %s, gnb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_GNB or CELL_HOME_GNB !\n", - RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); - } - - S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); - S1AP_REGISTER_ENB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; + paramdef_t NGParams[] = GNBNGPARAMS_DESC; + paramlist_def_t NGParamList = {GNB_CONFIG_STRING_AMF_IP_ADDRESS,NULL,0}; + + paramdef_t SCTPParams[] = GNBSCTPPARAMS_DESC; + paramdef_t NETParams[] = GNBNETPARAMS_DESC; + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k); + + NGAP_REGISTER_GNB_REQ (msg_p).gNB_id = gnb_id; + + if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_MACRO_GNB; + } else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) { + NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_HOME_ENB; + } else { + AssertFatal (0, + "Failed to parse gNB configuration file %s, gnb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_GNB or CELL_HOME_GNB !\n", + RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); + } + + NGAP_REGISTER_GNB_REQ (msg_p).gNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); + NGAP_REGISTER_GNB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; AssertFatal(!GNBParamList.paramarray[k][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr && !GNBParamList.paramarray[k][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, "It seems that you use an old configuration file. Please change the existing\n" @@ -831,100 +870,116 @@ int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i) { AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", PLMNParamList.numelt); - S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt; + NGAP_REGISTER_GNB_REQ(msg_p).num_plmn = PLMNParamList.numelt; for (int l = 0; l < PLMNParamList.numelt; ++l) { - - S1AP_REGISTER_ENB_REQ (msg_p).mcc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - S1AP_REGISTER_ENB_REQ (msg_p).mnc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; - S1AP_REGISTER_ENB_REQ (msg_p).default_drx = 0; - AssertFatal((S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l] == 2) || - (S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l] == 3), - "BAD MNC DIGIT LENGTH %d", - S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length[l]); - } - sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k); - config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix); - - S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0; - - for (int l = 0; l < S1ParamList.numelt; l++) { - - S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1; - - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][GNB_MME_IPV4_ADDRESS_IDX].strptr)); - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][GNB_MME_IPV6_ADDRESS_IDX].strptr)); + char snssaistr[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(snssaistr, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); + config_getlist(&SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams)/sizeof(paramdef_t), snssaistr); - if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_ACTIVE_IDX].strptr), "yes") == 0) { - } - if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1; - } else if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1; - } else if (strcmp(*(S1ParamList.paramarray[l][GNB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1; - S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1; - } + NGAP_REGISTER_GNB_REQ (msg_p).mcc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + NGAP_REGISTER_GNB_REQ (msg_p).mnc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; + NGAP_REGISTER_GNB_REQ (msg_p).default_drx = 0; + AssertFatal((NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] == 2) || + (NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] == 3), + "BAD MNC DIGIT LENGTH %d", + NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l]); + + NGAP_REGISTER_GNB_REQ (msg_p).num_nssai[l] = SNSSAIParamList.numelt; + for (int s = 0; s < SNSSAIParamList.numelt; ++s) { + + NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sST = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERIVE_TYPE_IDX].uptr; + NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD_flag = 0; + if(*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr != 0) { + NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD_flag = 1; + NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[0] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0xFF0000) >> 16; + NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[1] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0x00FF00) >> 8; + NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[2] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0x0000FF); + } + } + } + sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k); + config_getlist( &NGParamList,NGParams,sizeof(NGParams)/sizeof(paramdef_t),aprefix); + + NGAP_REGISTER_GNB_REQ (msg_p).nb_amf = 0; + + for (int l = 0; l < NGParamList.numelt; l++) { + + NGAP_REGISTER_GNB_REQ (msg_p).nb_amf += 1; + + strcpy(NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[l].ipv4_address,*(NGParamList.paramarray[l][GNB_AMF_IPV4_ADDRESS_IDX].strptr)); + strcpy(NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[l].ipv6_address,*(NGParamList.paramarray[l][GNB_AMF_IPV6_ADDRESS_IDX].strptr)); - if (S1ParamList.paramarray[l][GNB_MME_BROADCAST_PLMN_INDEX].iptr) - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][GNB_MME_BROADCAST_PLMN_INDEX].numelt; + if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_ACTIVE_IDX].strptr), "yes") == 0) { + } + if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { + NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv4 = 1; + } else if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { + NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 1; + } else if (strcmp(*(NGParamList.paramarray[l][GNB_AMF_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { + NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv4 = 1; + NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 1; + } + + if (NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].iptr) + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].numelt; else - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0; + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = 0; - AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, - "List of broadcast PLMN to be sent to MME can not be longer than actual " + AssertFatal(NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] <= NGAP_REGISTER_GNB_REQ(msg_p).num_plmn, + "List of broadcast PLMN to be sent to AMF can not be longer than actual " "PLMN list (max %d, but is %d)\n", - S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]); + NGAP_REGISTER_GNB_REQ(msg_p).num_plmn, + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l]); - for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) { + for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l]; ++el) { /* UINTARRAY gets mapped to int, see config_libconfig.c:223 */ - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][GNB_MME_BROADCAST_PLMN_INDEX].iptr[el]; - AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0 - && S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, - "index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n", - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el], - S1AP_REGISTER_ENB_REQ(msg_p).num_plmn); + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = NGParamList.paramarray[l][GNB_AMF_BROADCAST_PLMN_INDEX].iptr[el]; + AssertFatal(NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0 + && NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn, + "index for AMF's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n", + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el], + NGAP_REGISTER_GNB_REQ(msg_p).num_plmn); } /* if no broadcasst_plmn array is defined, fill default values */ - if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) { - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; + if (NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; - for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el) - S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el; + for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++el) + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = el; } - - } + + } - - // SCTP SETTING - S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; - S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; - if (EPC_MODE_ENABLED) { - sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG); - config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); - S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); - S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); - } + + // SCTP SETTING + NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; + if (AMF_MODE_ENABLED) { + sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); + NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); + } sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - // NETWORK_INTERFACES + // NETWORK_INTERFACES config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - - // S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); - cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr); - address = strtok(cidr, "/"); - - S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0; - S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4 = 1; - - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, address); - - break; - } - } + + // NGAP_REGISTER_GNB_REQ (msg_p).enb_interface_name_for_NGU = strdup(enb_interface_name_for_NGU); + cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr); + address = strtok(cidr, "/"); + + NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv6 = 0; + NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4 = 1; + + strcpy(NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4_address, address); + + break; + } + } } } } @@ -968,7 +1023,7 @@ void NRRCConfig(void) { paramdef_t GNBSParams[] = GNBSPARAMS_DESC; /* get global parameters, defined outside any section in the config file */ - + LOG_I(GNB_APP, "Getting GNBSParams\n"); config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); @@ -991,27 +1046,32 @@ void NRRCConfig(void) { } + int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { int J, l; char *address = NULL; char *cidr = NULL; - //int num_gnbs = 0; //int num_component_carriers = 0; int j,k = 0; int32_t gnb_id = 0; paramdef_t GNBSParams[] = GNBSPARAMS_DESC; + ////////// Identification parameters paramdef_t GNBParams[] = GNBPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; /* get global parameters, defined outside any section in the config file */ config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); - - //paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0}; + NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t)); + uint64_t ssb_bitmap=0xff; + memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t)); + prepare_scc(scc); + paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc); + paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0}; AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt, "Failed to parse config file %s, %uth attribute %s \n", - RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS); + RC.config_file_name, i, GNB_CONFIG_STRING_ACTIVE_GNBS); if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) { // Output a list of all gNBs. @@ -1021,10 +1081,10 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { for (k = 0; k < GNBParamList.numelt; k++) { if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { // Calculate a default eNB ID - if (EPC_MODE_ENABLED) { + if (AMF_MODE_ENABLED) { uint32_t hash; - hash = s1ap_generate_eNB_id (); - gnb_id = k + (hash & 0xFFFF8); + hash = ngap_generate_gNB_id (); + gnb_id = k + (hash & 0xFFFFFF8); } else { gnb_id = k; } @@ -1081,19 +1141,28 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", X2AP_REGISTER_ENB_REQ(msg_p).mnc); - X2AP_REGISTER_ENB_REQ (msg_p).num_cc = 1; - J = 0; - X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = 78; //ccparams_nr_x2.nr_band; //78 - X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = 3600000000; //ccparams_nr_x2.downlink_frequency; //3600000000 - X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = 0; //(unsigned int) ccparams_nr_x2.uplink_frequency_offset; //0 - X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= 0; //ccparams_nr_x2.Nid_cell; //0 - X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= 106; //ccparams_nr_x2.N_RB_DL; //106 + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); - X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; - - //Temp out - /*X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL); - X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);*/ + config_getlist(&SCCsParamList, NULL, 0, aprefix); + if (SCCsParamList.numelt > 0) { + sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0); + config_get( SCCsParams,sizeof(SCCsParams)/sizeof(paramdef_t),aprefix); + fix_scc(scc,ssb_bitmap); + } + X2AP_REGISTER_ENB_REQ (msg_p).num_cc = SCCsParamList.numelt; + for (J = 0; J < SCCsParamList.numelt ; J++) { + X2AP_REGISTER_ENB_REQ (msg_p).nr_band[J] = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; //nr_band; //78 + X2AP_REGISTER_ENB_REQ (msg_p).nrARFCN[J] = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; + X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; //0 + X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= *scc->physCellId; //0 + X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;//106 + X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD; + LOG_I(X2AP, "gNB configuration parameters: nr_band: %d, nr_ARFCN: %d, DL_RBs: %d, num_cc: %d \n", + X2AP_REGISTER_ENB_REQ (msg_p).nr_band[J], + X2AP_REGISTER_ENB_REQ (msg_p).nrARFCN[J], + X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J], + X2AP_REGISTER_ENB_REQ (msg_p).num_cc); + } sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k); config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix); @@ -1150,7 +1219,7 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; - if (EPC_MODE_ENABLED) { + if (AMF_MODE_ENABLED) { sprintf(aprefix,"%s.[%i].%s",GNB_CONFIG_STRING_GNB_LIST,k,GNB_CONFIG_STRING_SCTP_CONFIG); config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); X2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); @@ -1182,4 +1251,3 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { return 0; } - diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index e2588d9e4d..0d965171ef 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -39,6 +39,7 @@ #include "platform_constants.h" #include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" +#include "ngap_messages_types.h" #ifdef CMAKER #include "rrc_messages_types.h" @@ -102,7 +103,7 @@ extern void NRRCConfig(void); //void ru_config_display(void); void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc); -int RCconfig_NR_S1(MessageDef *msg_p, uint32_t i); +int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); #endif /* GNB_CONFIG_H_ */ diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 84da1de530..f1fe0c97c9 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -78,7 +78,6 @@ typedef enum { #define GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none" #define GNB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING "annoying" #define GNB_CONFIG_STRING_ASN1_VERBOSITY_INFO "info" - /* global parameters, not under a specific section */ #define GNB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity" @@ -91,6 +90,7 @@ typedef enum { {GNB_CONFIG_STRING_ASN1_VERBOSITY, NULL, 0, uptr:NULL, defstrval:GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_ACTIVE_GNBS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRINGLIST, 0} \ } + #define GNB_ASN1_VERBOSITY_IDX 0 #define GNB_ACTIVE_GNBS_IDX 1 @@ -118,30 +118,6 @@ typedef enum { #define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10" #define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10" - -typedef struct ccparams_nr_x2 { - char *frame_type; - int32_t tdd_config; - int32_t tdd_config_s; - int32_t nr_band; - long long int downlink_frequency; - int32_t uplink_frequency_offset; - int32_t Nid_cell; - int32_t N_RB_DL; - } ccparams_nr_x2_t; - - -#define CCPARAMS_NR_X2_DESC(ccparams) { \ - {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"TDD", 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_EUTRA_BAND, NULL, 0, iptr:&ccparams.nr_band, defintval:78, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:3600000000, TYPE_UINT64, 0}, \ - {ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:0, 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:106, TYPE_UINT, 0} \ -} - /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* cell configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -150,7 +126,7 @@ typedef struct ccparams_nr_x2 { {GNB_CONFIG_STRING_GNB_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_CELL_TYPE, NULL, 0, strptr:NULL, defstrval:"CELL_MACRO_GNB", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_NAME, NULL, 0, strptr:NULL, defstrval:"OAIgNodeB", TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, strptr:NULL, defstrval:"0", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_TRACKING_AREA_CODE, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_MOBILE_COUNTRY_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_MOBILE_NETWORK_CODE_OLD, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ @@ -236,38 +212,58 @@ typedef struct ccparams_nr_x2 { } +/* SNSSAI ID configuration */ +#define GNB_CONFIG_STRING_SNSSAI_LIST "snssaiList" +#define GNB_CONFIG_STRING_SLICE_SERIVE_TYPE "sst" +#define GNB_CONFIG_STRING_SLICE_DIFFERENTIATOR "sd" -/* MME configuration parameters section name */ -#define GNB_CONFIG_STRING_MME_IP_ADDRESS "mme_ip_address" +#define GNB_SLICE_SERIVE_TYPE_IDX 0 +#define GNB_SLICE_DIFFERENTIATOR_IDX 1 + +#define GNBSNSSAIPARAMS_DESC { \ +/* optname helpstr paramflags XXXptr def val type numelt */ \ + {GNB_CONFIG_STRING_SLICE_SERIVE_TYPE, "slice serive type", 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ + {GNB_CONFIG_STRING_SLICE_DIFFERENTIATOR, "slice differentiator", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +} + +#define SLICE_SERIVE_TYPE_OKRANGES {1,2,3,4} + +#define SNSSAIPARAMS_CHECK { \ + { .s1 = { config_check_intval, SLICE_SERIVE_TYPE_OKRANGES, 4 } }, \ + { .s5 = { NULL } }, \ +} + +/* AMF configuration parameters section name */ +#define GNB_CONFIG_STRING_AMF_IP_ADDRESS "amf_ip_address" /* SRB1 configuration parameters names */ -#define GNB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4" -#define GNB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6" -#define GNB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active" -#define GNB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference" -#define GNB_CONFIG_STRING_MME_BROADCAST_PLMN_INDEX "broadcast_plmn_index" +#define GNB_CONFIG_STRING_AMF_IPV4_ADDRESS "ipv4" +#define GNB_CONFIG_STRING_AMF_IPV6_ADDRESS "ipv6" +#define GNB_CONFIG_STRING_AMF_IP_ADDRESS_ACTIVE "active" +#define GNB_CONFIG_STRING_AMF_IP_ADDRESS_PREFERENCE "preference" +#define GNB_CONFIG_STRING_AMF_BROADCAST_PLMN_INDEX "broadcast_plmn_index" /*-------------------------------------------------------------------------------------------------------------------------------------*/ /* MME configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-------------------------------------------------------------------------------------------------------------------------------------*/ -#define GNBS1PARAMS_DESC { \ -{GNB_CONFIG_STRING_MME_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_MME_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +#define GNBNGPARAMS_DESC { \ +{GNB_CONFIG_STRING_AMF_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_AMF_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_AMF_IP_ADDRESS_ACTIVE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_AMF_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ } -#define GNB_MME_IPV4_ADDRESS_IDX 0 -#define GNB_MME_IPV6_ADDRESS_IDX 1 -#define GNB_MME_IP_ADDRESS_ACTIVE_IDX 2 -#define GNB_MME_IP_ADDRESS_PREFERENCE_IDX 3 -#define GNB_MME_BROADCAST_PLMN_INDEX 4 +#define GNB_AMF_IPV4_ADDRESS_IDX 0 +#define GNB_AMF_IPV6_ADDRESS_IDX 1 +#define GNB_AMF_IP_ADDRESS_ACTIVE_IDX 2 +#define GNB_AMF_IP_ADDRESS_PREFERENCE_IDX 3 +#define GNB_AMF_BROADCAST_PLMN_INDEX 4 /*---------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------*/ /* SCTP configuration parameters section name */ @@ -295,11 +291,11 @@ typedef struct ccparams_nr_x2 { /* S1 interface configuration parameters section name */ #define GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" -#define GNB_INTERFACE_NAME_FOR_S1_MME_IDX 0 -#define GNB_IPV4_ADDRESS_FOR_S1_MME_IDX 1 -#define GNB_INTERFACE_NAME_FOR_S1U_IDX 2 -#define GNB_IPV4_ADDR_FOR_S1U_IDX 3 -#define GNB_PORT_FOR_S1U_IDX 4 +#define GNB_INTERFACE_NAME_FOR_NG_AMF_IDX 0 +#define GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX 1 +#define GNB_INTERFACE_NAME_FOR_NGU_IDX 2 +#define GNB_IPV4_ADDR_FOR_NGU_IDX 3 +#define GNB_PORT_FOR_NGU_IDX 4 #define GNB_IPV4_ADDR_FOR_X2C_IDX 5 #define GNB_PORT_FOR_X2C_IDX 6 @@ -307,9 +303,15 @@ typedef struct ccparams_nr_x2 { #define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME "GNB_INTERFACE_NAME_FOR_S1_MME" #define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME "GNB_IPV4_ADDRESS_FOR_S1_MME" #define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U "GNB_INTERFACE_NAME_FOR_S1U" -#define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U "GNB_IPV4_ADDRESS_FOR_S1U" +#define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U "GNB_IPV4_ADDRESS_FOR_S1U" #define GNB_CONFIG_STRING_GNB_PORT_FOR_S1U "GNB_PORT_FOR_S1U" +#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF "GNB_INTERFACE_NAME_FOR_NG_AMF" +#define GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF "GNB_IPV4_ADDRESS_FOR_NG_AMF" +#define GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU "GNB_INTERFACE_NAME_FOR_NGU" +#define GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU "GNB_IPV4_ADDRESS_FOR_NGU" +#define GNB_CONFIG_STRING_GNB_PORT_FOR_NGU "GNB_PORT_FOR_NGU" + /* X2 interface configuration parameters names */ #define GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C "GNB_IPV4_ADDRESS_FOR_X2C" #define GNB_CONFIG_STRING_ENB_PORT_FOR_X2C "GNB_PORT_FOR_X2C" @@ -319,11 +321,11 @@ typedef struct ccparams_nr_x2 { /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------*/ #define GNBNETPARAMS_DESC { \ -{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1_MME, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \ +{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_NG_AMF, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0} \ } @@ -335,8 +337,11 @@ typedef struct ccparams_nr_x2 { /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define GNBGTPUPARAMS_DESC { \ +{GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_NGU, NULL, 0, strptr:&gnb_interface_name_for_NGU, defstrval:"lo", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_NGU, NULL, 0, strptr:&gnb_ipv4_address_for_NGU, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_PORT_FOR_NGU, NULL, 0, uptr:&gnb_port_for_NGU, defintval:2152, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_GNB_INTERFACE_NAME_FOR_S1U, NULL, 0, strptr:&gnb_interface_name_for_S1U, defstrval:"lo", TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_GNB_IPV4_ADDR_FOR_S1U, NULL, 0, strptr:&gnb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{GNB_CONFIG_STRING_GNB_IPV4_ADDRESS_FOR_S1U, NULL, 0, strptr:&gnb_ipv4_address_for_S1U, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_GNB_PORT_FOR_S1U, NULL, 0, uptr:&gnb_port_for_S1U, defintval:2152, TYPE_UINT, 0} \ } /*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 8f5aab99a7..ccbff6a5eb 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -473,7 +473,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id, if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) { // note: probably ul_failure_timer should be less than UE radio link failure time(see T310/N310/N311) if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) { - MessageDef *m = itti_alloc_new_message(TASK_MAC_ENB, F1AP_UE_CONTEXT_RELEASE_REQ); + MessageDef *m = itti_alloc_new_message(TASK_MAC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); F1AP_UE_CONTEXT_RELEASE_REQ(m).rnti = rnti; F1AP_UE_CONTEXT_RELEASE_REQ(m).cause = F1AP_CAUSE_RADIO_NETWORK; F1AP_UE_CONTEXT_RELEASE_REQ(m).cause_value = 1; // 1 = F1AP_CauseRadioNetwork_rl_failure @@ -596,13 +596,41 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); if (((frameP & 127) == 0) && (subframeP == 0)) { - LOG_I(MAC,"UE rnti %x : %s, PHR %d dB DL CQI %d PUSCH SNR %d PUCCH SNR %d\n", + double total_bler; + if(UE_scheduling_control->pusch_rx_num[CC_id] == 0 && UE_scheduling_control->pusch_rx_error_num[CC_id] == 0) { + total_bler = 0; + } + else { + total_bler = (double)UE_scheduling_control->pusch_rx_error_num[CC_id] / (double)(UE_scheduling_control->pusch_rx_error_num[CC_id] + UE_scheduling_control->pusch_rx_num[CC_id]) * 100; + } + LOG_I(MAC,"UE %x : %s, PHR %d DLCQI %d PUSCH %d PUCCH %d RLC disc %d UL-stat rcv %lu err %lu bler %lf mcsoff %d bsr %u sched %u tbs %lu cnt %u , DL-stat tbs %lu cnt %u rb %u buf %u 1st %u ret %u ri %d\n", rnti, UE_scheduling_control->ul_out_of_sync == 0 ? "in synch" : "out of sync", UE_info->UE_template[CC_id][UE_id].phr_info, UE_scheduling_control->dl_cqi[CC_id], - (5 * UE_scheduling_control->pusch_snr[CC_id] - 640) / 10, - (5 * UE_scheduling_control->pucch1_snr[CC_id] - 640) / 10); + UE_scheduling_control->pusch_snr_avg[CC_id], + UE_scheduling_control->pucch1_snr[CC_id], + UE_scheduling_control->rlc_out_of_resources_cnt, + UE_scheduling_control->pusch_rx_num[CC_id], + UE_scheduling_control->pusch_rx_error_num[CC_id], + total_bler, + UE_scheduling_control->mcs_offset[CC_id], + UE_info->UE_template[CC_id][UE_id].estimated_ul_buffer, + UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes, + UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes_rx, + UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus_rx, + UE_info->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes, + UE_info->eNB_UE_stats[CC_id][UE_id].total_num_pdus, + UE_info->eNB_UE_stats[CC_id][UE_id].total_rbs_used, +#if defined(PRE_SCD_THREAD) + UE_info->UE_template[CC_id][UE_id].dl_buffer_total, +#else + 0, +#endif + UE_scheduling_control->first_cnt[CC_id], + UE_scheduling_control->ret_cnt[CC_id], + UE_scheduling_control->aperiodic_ri_received[CC_id] + ); } RC.eNB[module_idP][CC_id]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = -63; @@ -914,7 +942,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, #if (!defined(PRE_SCD_THREAD)) if (!NODE_IS_DU(RC.rrc[module_idP]->node_type)) { + void rlc_tick(int, int); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP); + rlc_tick(frameP, subframeP); pdcp_run(&ctxt); pdcp_mbms_run(&ctxt); rrc_rx_tx(&ctxt, CC_id); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index d1365b9ac3..3dea211dbc 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -212,13 +212,6 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - if (NFAPI_MODE != NFAPI_MONOLITHIC) { - oai_nfapi_hi_dci0_req(hi_dci0_req); - hi_dci0_req_body->number_of_hi=0; - } - - LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi); - // save UL scheduling information for preprocessor for (j = 0; j < ra->msg3_nb_rb; j++) cc->vrb_map_UL[ra->msg3_first_rb + j] = 1; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 1f99f50ece..b516b04e03 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -821,6 +821,7 @@ schedule_ue_spec(module_id_t module_idP, /* reset ta_update */ ue_sched_ctrl->ta_update = 31; + ue_sched_ctrl->ta_update_f = 31.0; } int ta_len = (ta_update != 31) ? 2 : 0; @@ -1050,7 +1051,7 @@ schedule_ue_spec(module_id_t module_idP, // this is the snr // unit is not dBm, it's special from nfapi // converting to dBm - int snr = (5 * ue_sched_ctrl->pucch1_snr[CC_id] - 640) / 10; + int snr = ue_sched_ctrl->pucch1_snr[CC_id]; int target_snr = eNB->puCch10xSnr / 10; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out @@ -1366,6 +1367,7 @@ schedule_ue_spec_br(module_id_t module_idP, /* Reset ta_update */ ue_sched_ctl->ta_update = 31; + ue_sched_ctl->ta_update_f = 31.0; } else { ta_update = 31; } @@ -1684,7 +1686,7 @@ schedule_ue_spec_br(module_id_t module_idP, /* Do PUCCH power control */ /* This is the snr */ /* unit is not dBm, it's special from nfapi, convert to dBm */ - snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10; + snr = ue_sched_ctl->pucch1_snr[CC_id]; target_snr = mac->puCch10xSnr / 10; /* This assumes accumulated tpc */ /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index f6220fa46d..23137b7887 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -61,7 +61,9 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); /* internal vars */ DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]; int last_dlsch_ue_id[MAX_NUM_CCs] = {-1}; +int last_dlsch_ue_id_volte[MAX_NUM_CCs] = {-1}; int last_ulsch_ue_id[MAX_NUM_CCs] = {-1}; +int last_ulsch_ue_id_volte[MAX_NUM_CCs] = {-1}; #if defined(PRE_SCD_THREAD) uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -1567,6 +1569,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, /* reset ta_update */ ue_sched_ctl->ta_update = 31; + ue_sched_ctl->ta_update_f = 31.0; } else { ta_update = 31; } @@ -1998,14 +2001,15 @@ schedule_ue_spec_fairRR(module_id_t module_idP, // this is the snr eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id]; /* Unit is not dBm, it's special from nfapi */ - snr = (5 * ue_sched_ctl->pucch1_snr[CC_id] - 640) / 10; - target_snr = eNB->puCch10xSnr / 10; + snr = ue_sched_ctl->pucch1_snr[CC_id]; + target_snr = eNB->puCch10xSnr/10; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out int32_t framex10psubframe = UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + int pucch_tpc_interval=10; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around + if (((framex10psubframe+pucch_tpc_interval)<=(frameP*10+subframeP)) || //normal case + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=pucch_tpc_interval)))) //frame wrap-around if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; UE_info->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; @@ -2300,6 +2304,18 @@ void ulsch_scheduler_pre_ue_select_fairRR( } } + if (mac_eNB_get_rrc_status(module_idP, rnti) == RRC_HO_EXECUTION) { + aggregation = 4; + + if(get_aggregation(get_bw_index(module_idP, CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0)>4) + aggregation = get_aggregation(get_bw_index(module_idP, CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + }else{ + //aggregation = 2; + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id], + format0); + } + cc = &eNB->common_channels[CC_id]; //harq_pid harq_pid = subframe2harqpid(cc,(frameP+(sched_subframePUE_template[CC_id][UE_id].estimated_ul_buffer - UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes; - if (bytes_to_schedule < 0) bytes_to_schedule = 0; + if (bytes_to_schedule < 0) { + bytes_to_schedule = 0; + UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes = 0; + } if ( UE_id > last_ulsch_ue_id[CC_id] && ((ulsch_ue_select[CC_id].ue_num+ue_first_num[CC_id]) < ulsch_ue_max_num[CC_id]) ) { if ( bytes_to_schedule > 0 ) { @@ -2351,9 +2370,9 @@ void ulsch_scheduler_pre_ue_select_fairRR( UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); - if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || + if ( ((UE_sched_ctl->ul_inactivity_timer>64)&&(UE_sched_ctl->ul_scheduled==0)) || ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) || - ((UE_sched_ctl->cqi_req_timer>300)&&((rrc_status >= RRC_CONNECTED))) ) { + ((UE_sched_ctl->cqi_req_timer>64)&&((rrc_status >= RRC_CONNECTED))) ) { first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; ue_first_num[CC_id]++; @@ -2457,16 +2476,28 @@ void ulsch_scheduler_pre_ue_select_fairRR( UE_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; int bytes_to_schedule = UE_info->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes; - if (bytes_to_schedule < 0) bytes_to_schedule = 0; + if (bytes_to_schedule < 0) { + bytes_to_schedule = 0; + UE_info->UE_template[CC_id][UE_id].scheduled_ul_bytes = 0; + } rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); if ( (bytes_to_schedule > 0) || (UE_info->UE_template[CC_id][UE_id].ul_SR > 0) || - ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || + ((UE_sched_ctl->ul_inactivity_timer>64)&&(UE_sched_ctl->ul_scheduled==0)) || ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(rrc_status < RRC_CONNECTED)) || - ((UE_sched_ctl->cqi_req_timer>300)&&((rrc_status >= RRC_CONNECTED))) ) { + ((UE_sched_ctl->cqi_req_timer>64)&&((rrc_status >= RRC_CONNECTED))) ) { hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; - aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + if (mac_eNB_get_rrc_status(module_idP, rnti) == RRC_HO_EXECUTION) { + aggregation = 4; + + if(get_aggregation(get_bw_index(module_idP, CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0)>4) + aggregation = get_aggregation(get_bw_index(module_idP, CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + }else { + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id], + format0); + } if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; @@ -2569,7 +2600,10 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, uint8_t total_rbs=0; uint8_t average_rbs; uint16_t first_rb[MAX_NUM_CCs]; - uint8_t mcs; + int8_t mcs; + uint8_t snr; + double bler_filter=0.9; + double bler; uint8_t rb_table_index; uint8_t num_pucch_rb; uint32_t tbs; @@ -2663,33 +2697,74 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, } else { UE_template = &UE_info->UE_template[CC_id][UE_id]; - if ( UE_info->UE_sched_ctrl[UE_id].phr_received == 1 ) { - mcs = 20; - } else { - mcs = 10; + int32_t framex10psubframe = UE_template->pusch_bler_calc_frame*10+UE_template->pusch_bler_calc_subframe; + int pusch_bler_interval=50; + double total_bler; + + if(UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id] == 0 && UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] == 0) { + total_bler = 0; + } + else { + total_bler = (double)UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] / (double)(UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id]) * 100; + } + + if (((framex10psubframe+pusch_bler_interval)<=(frameP*10+subframeP)) || //normal case + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=pusch_bler_interval)))) { //frame wrap-around + + UE_template->pusch_bler_calc_frame=frameP; + UE_template->pusch_bler_calc_subframe=subframeP; + + int pusch_rx_num_diff = UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id] - UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[CC_id]; + int pusch_rx_error_num_diff = UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id] - UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[CC_id]; + + if((pusch_rx_num_diff == 0) && (pusch_rx_error_num_diff == 0)) { /* first rx case or no rx among interval time */ + bler = UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id]; + } + else { + bler = (double)pusch_rx_error_num_diff / (double)(pusch_rx_num_diff + pusch_rx_error_num_diff) * 100; + } + UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id] * bler_filter + bler * (1.0-bler_filter); + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id]; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[CC_id] = UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id]; + + if(bler < 0.5) { + if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] !=0) { + UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]--; + } + } + if(bler >= 2) { + UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]++; + if(UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id] >= 20) { + UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]=20; + } + } + } + + snr = UE_info->UE_sched_ctrl[UE_id].pusch_snr_avg[CC_id]; + + mcs = 20 - UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id]; + if(mcs < 6) { + mcs = 6; } if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST ) { int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; - if (bytes_to_schedule < 0) bytes_to_schedule = 0; + if (bytes_to_schedule < 0) { + bytes_to_schedule = 0; + UE_template->scheduled_ul_bytes = 0; + } if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) { rb_table_index = 2; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); - - while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > bytes_to_schedule)) && (mcs > 3) ) { - mcs--; - tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); - } + tx_power = (int8_t)(hundred_times_log10_NPRB[rb_table[rb_table_index] - 1] / 100); while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { rb_table_index++; tbs = get_TBS_UL(mcs,rb_table[rb_table_index]); - tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0); + tx_power = (int8_t)(hundred_times_log10_NPRB[rb_table[rb_table_index] - 1] / 100); } if ( rb_table[rb_table_index]<3 ) { @@ -2719,6 +2794,10 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, UE_info->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index; UE_info->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } + LOG_D(MAC,"[eNB %hu] frame %u subframe %u, UE %d/%x CC %d snr %hhu snr_inst %hhu mcs %hhd mcs_offset %hhu bler %lf total_bler %lf ( %lu %lu ) rb_num %hhu phr_info %hhd tx_power %hd bsr %d estimated_ul_buffer %d scheduled_ul_bytes %d\n", + module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id, snr, UE_info->UE_sched_ctrl[UE_id].pusch_snr[CC_id], mcs, UE_info->UE_sched_ctrl[UE_id].mcs_offset[CC_id], UE_info->UE_sched_ctrl[UE_id].pusch_bler[CC_id], + total_bler, UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[CC_id], UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[CC_id], rb_table[rb_table_index-1], UE_template->phr_info, tx_power, bytes_to_schedule, UE_template->estimated_ul_buffer, UE_template->scheduled_ul_bytes); + } else { if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) { // assigne RBS( 6 RBs) @@ -3032,12 +3111,24 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; harq_pid = subframe2harqpid(cc,sched_frame,sched_subframeP); rnti = UE_RNTI(CC_id,UE_id); - aggregation=get_aggregation(get_bw_index(module_idP,CC_id),UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + if (mac_eNB_get_rrc_status(module_idP, rnti) == RRC_HO_EXECUTION) { + aggregation = 4; + if(get_aggregation(get_bw_index(module_idP, CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0)>4) + aggregation = get_aggregation(get_bw_index(module_idP, CC_id),UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format0); + }else{ + //aggregation = 2; + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id], + format0); + } LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL); int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; - if (bytes_to_schedule < 0) bytes_to_schedule = 0; + if (bytes_to_schedule < 0) { + bytes_to_schedule = 0; + UE_template->scheduled_ul_bytes = 0; + } RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = bytes_to_schedule; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); @@ -3051,7 +3142,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_sched_ctrl->cqi_received = 0; UE_sched_ctrl->cqi_req_timer = 0; cqi_req = 0; - }else if (UE_sched_ctrl->cqi_req_timer>30) { + }else if (UE_sched_ctrl->cqi_req_timer>64) { cqi_req = 1; // To be safe , do not ask CQI in special SFs:36.213/7.2.3 CQI definition @@ -3082,14 +3173,15 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, //power control //compute the expected ULSCH RX power (for the stats) // this is the normalized RX power and this should be constant (regardless of mcs - snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; + snr = UE_sched_ctrl->pusch_snr_avg[CC_id]; target_snr = eNB->puSch10xSnr / 10; // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; + int pusch_tpc_interval=500; - if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) { //frame wrap-around + if (((framex10psubframe+pusch_tpc_interval)<=(frameP*10+subframeP)) || //normal case + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=pusch_tpc_interval)))) { //frame wrap-around UE_template->pusch_tpc_tx_frame=frameP; UE_template->pusch_tpc_tx_subframe=subframeP; @@ -3133,6 +3225,17 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, UE_template->mcs_UL[harq_pid]=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); rb_table_index=5; // for PHR } + if( (UE_sched_ctrl->ul_scheduled | (1<0 ){ + UE_template->scheduled_ul_bytes -= UE_template->TBS_UL[harq_pid]; + + if (UE_template->scheduled_ul_bytes < 0) { + UE_template->scheduled_ul_bytes = 0; + } + UE_template->estimated_ul_buffer -= UE_template->TBS_UL[harq_pid]; + if (UE_template->estimated_ul_buffer < 0) { + UE_template->estimated_ul_buffer = 0; + } + } UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid]; UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); @@ -3194,8 +3297,8 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, nfapi_hi_dci0_request_t *nfapi_hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP]; nfapi_hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! nfapi_hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d mcs %d first_rb %d num_rb %d round %d mcs %d sinr %d bler %lf\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,UE_template->mcs_UL[harq_pid],first_rb[CC_id],rb_table[rb_table_index],0,UE_template->mcs_UL[harq_pid],UE_sched_ctrl->pusch_snr_avg[CC_id],UE_sched_ctrl->pusch_bler[CC_id]); ul_req_index = 0; dlsch_flag = 0; @@ -3309,7 +3412,6 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, mcs_rv = 31; } - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb); UE_info->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) @@ -3345,8 +3447,9 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; hi_dci0_req->number_of_dci++; // Add UL_config PDUs - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d mcs %d first_rb %d num_rb %d round %d mcs %d sinr %d bler %lf\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,mcs_rv,ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb,ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb,UE_sched_ctrl->round_UL[CC_id][harq_pid],UE_template->mcs_UL[harq_pid],UE_sched_ctrl->pusch_snr_avg[CC_id],UE_sched_ctrl->pusch_bler[CC_id]); + ul_req_index = 0; dlsch_flag = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c index 689db8e208..1e595f11b5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -238,7 +238,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s //power control //compute the expected ULSCH RX power (for the stats) // this is the snr and this should be constant (regardless of mcs) - snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; + snr = UE_sched_ctrl->pusch_snr[CC_id]; // new transmission ndi = 1-UE_template->oldNDI_UL[harq_pid]; UE_template->oldNDI_UL[harq_pid]=ndi; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 89c2ecc83d..bd3c428828 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2173,6 +2173,7 @@ add_new_ue(module_id_t mod_idP, ) //------------------------------------------------------------------------------ { + eNB_MAC_INST *eNB = RC.mac[mod_idP]; int UE_id; int i, j; UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info; @@ -2215,7 +2216,19 @@ add_new_ue(module_id_t mod_idP, 0, sizeof(eNB_UE_STATS)); UE_info->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; + UE_info->UE_sched_ctrl[UE_id].ta_update_f = 31.0; UE_info->UE_sched_ctrl[UE_id].ta_update = 31; + UE_info->UE_sched_ctrl[UE_id].pusch_snr[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_cqi_f[cc_idP] = (eNB->puSch10xSnr+640)/5; + UE_info->UE_sched_ctrl[UE_id].pusch_cqi[cc_idP] = (eNB->puSch10xSnr+640)/5; + UE_info->UE_sched_ctrl[UE_id].pusch_snr_avg[cc_idP] = eNB->puSch10xSnr/10; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_num_old[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_rx_error_num_old[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].pusch_bler[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].ret_cnt[cc_idP] = 0; + UE_info->UE_sched_ctrl[UE_id].first_cnt[cc_idP] = 0; for (j = 0; j < 8; j++) { UE_info->UE_template[cc_idP][UE_id].oldNDI[j] = 0; @@ -4934,6 +4947,7 @@ cqi_indication(module_id_t mod_idP, { int UE_id = find_UE_id(mod_idP, rntiP); UE_info_t *UE_info = &RC.mac[mod_idP]->UE_info; + uint64_t pdu_val = *(uint64_t *) pdu; if (UE_id == -1) { LOG_W(MAC, "cqi_indication: UE %x not found\n", rntiP); @@ -4973,10 +4987,10 @@ cqi_indication(module_id_t mod_idP, subframeP, pdu, rel9->length); - LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n", + LOG_D(MAC,"Frame %d Subframe %d update CQI:%d pdu 0x%016"PRIx64"\n", frameP, subframeP, - sched_ctl->dl_cqi[CC_idP]); + sched_ctl->dl_cqi[CC_idP],pdu_val); sched_ctl->cqi_req_flag &= (~(1 << subframeP)); sched_ctl->cqi_received = 1; } @@ -5164,7 +5178,7 @@ harq_indication(module_id_t mod_idP, /* don't care about cqi reporting if NACK/DTX is there */ if (channel == 0 && !nack_or_dtx_reported(cc, harq_pdu)) { - sched_ctl->pucch1_snr[CC_idP] = ul_cqi; + sched_ctl->pucch1_snr[CC_idP] = (5 * ul_cqi - 640) / 10; sched_ctl->pucch1_cqi_update[CC_idP] = 1; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 2de45db856..47c27798bf 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -56,6 +56,8 @@ #include "flexran.pb-c.h" #include "flexran_agent_mac.h" #include +#include + #include "T.h" @@ -158,13 +160,29 @@ rx_sdu(const module_id_t enb_mod_idP, UE_scheduling_control->ul_inactivity_timer = 0; UE_scheduling_control->ul_failure_timer = 0; UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid)); + UE_scheduling_control->pusch_rx_num[CC_idP]++; + /* Update with smoothing: 3/4 of old value and 1/4 of new. * This is the logic that was done in the function * lte_est_timing_advance_pusch, maybe it's not necessary? * maybe it's even not correct at all? */ - UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4; - UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; + UE_scheduling_control->ta_update_f = ((double)UE_scheduling_control->ta_update_f * 3 + (double)timing_advance) / 4; + UE_scheduling_control->ta_update = (int)UE_scheduling_control->ta_update_f; + int tmp_snr = (5 * ul_cqi - 640) / 10; + UE_scheduling_control->pusch_snr[CC_idP] = tmp_snr; + + if(tmp_snr > 0 && tmp_snr < 63) { + double snr_filter_tpc=0.7; + int snr_thres_tpc=30; + int diff = UE_scheduling_control->pusch_snr_avg[CC_idP] - UE_scheduling_control->pusch_snr[CC_idP]; + if(abs(diff) < snr_thres_tpc) { + UE_scheduling_control->pusch_cqi_f[CC_idP] = ((double)UE_scheduling_control->pusch_cqi_f[CC_idP] * snr_filter_tpc + (double)ul_cqi * (1-snr_filter_tpc)); + UE_scheduling_control->pusch_cqi[CC_idP] = (int)UE_scheduling_control->pusch_cqi_f[CC_idP]; + UE_scheduling_control->pusch_snr_avg[CC_idP] = (5 * UE_scheduling_control->pusch_cqi[CC_idP] - 640) / 10; + } + } + UE_scheduling_control->ul_consecutive_errors = 0; first_rb = UE_template_ptr->first_rb_ul[harq_pid]; @@ -180,7 +198,8 @@ rx_sdu(const module_id_t enb_mod_idP, UE_template_ptr->scheduled_ul_bytes = 0; } } else { // sduP == NULL => error - LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n", + UE_scheduling_control->pusch_rx_error_num[CC_idP]++; + LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n", enb_mod_idP, harq_pid, CC_idP, @@ -193,7 +212,7 @@ rx_sdu(const module_id_t enb_mod_idP, sdu_lenP); if (ul_cqi > 200) { // too high energy pattern - UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi; + UE_scheduling_control->pusch_snr[CC_idP] = (5 * ul_cqi - 640) / 10; LOG_W(MAC, "[MAC] Too high energy pattern\n"); } @@ -288,6 +307,23 @@ 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); + nfapi_hi_dci0_request_t *hi_dci0_req = NULL; + uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); + hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP + sf_ahead_dl) % 10]; + nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; + nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu); + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0; + hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0; + hi_dci0_req_body->number_of_hi++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 0); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl); + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; } else { 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) @@ -636,7 +672,7 @@ rx_sdu(const module_id_t enb_mod_idP, switch (rx_lcids[i]) { case CCCH: - if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + if ((rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) || (rx_lengths[i] < 0) || (rx_lengths[i] > (sdu_lenP - (payload_ptr - sduP)))) { LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", enb_mod_idP, CC_idP, @@ -757,6 +793,17 @@ rx_sdu(const module_id_t enb_mod_idP, LOG_T(MAC, "\n"); #endif + if ((rx_lengths[i] > DCH_PAYLOAD_SIZE_MAX) || (rx_lengths[i] < 0) || (rx_lengths[i] > (sdu_lenP - (payload_ptr - sduP)))) { + LOG_E(MAC, "[eNB %d/%d] frame %d received DCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + DCH_PAYLOAD_SIZE_MAX, + sdu_lenP); + break; + } + if (UE_id != -1) { if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) { /* Adjust buffer occupancy of the correponding logical channel group */ @@ -801,8 +848,18 @@ rx_sdu(const module_id_t enb_mod_idP, LOG_T(MAC, "\n"); #endif - if (rx_lcids[i] < NB_RB_MAX) { + if ((rx_lengths[i] > SCH_PAYLOAD_SIZE_MAX) || (rx_lengths[i] < 0) || (rx_lengths[i] > (sdu_lenP - (payload_ptr - sduP)))) { + LOG_E(MAC, "[eNB %d/%d] frame %d received DTCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + DCH_PAYLOAD_SIZE_MAX, + sdu_lenP); + UE_info->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + break; + } LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", enb_mod_idP, CC_idP, @@ -812,6 +869,25 @@ rx_sdu(const module_id_t enb_mod_idP, rx_lcids[i]); if (UE_id != -1) { + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti); + if (ue_contextP != NULL) { + if (ue_contextP->ue_context.DRB_active[rx_lcids[i] - 2] == 0) { + LOG_E(MAC, "[eNB %d/%d] frame %d received non active DTCH of size %d ( sdu_len %d, lcid %d), dropping packet\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + sdu_lenP,rx_lcids[i]); + UE_info->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + break; + } + }else{ + LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", + enb_mod_idP, + CC_idP, + current_rnti); + break; + } /* Adjust buffer occupancy of the correponding logical channel group */ LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", enb_mod_idP, @@ -835,48 +911,45 @@ rx_sdu(const module_id_t enb_mod_idP, UE_template_ptr->ul_buffer_info[1] + UE_template_ptr->ul_buffer_info[2] + UE_template_ptr->ul_buffer_info[3]; + if (UE_template_ptr->estimated_ul_buffer == 0) { + UE_template_ptr->scheduled_ul_bytes = 0; + } } - if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); UE_info->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; UE_info->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; /* Clear uplane_inactivity_timer */ UE_scheduling_control->uplane_inactivity_timer = 0; /* Reset RRC inactivity timer after uplane activity */ - ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti); - - if (ue_contextP != NULL) { ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; - } else { - LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", - enb_mod_idP, - CC_idP, - current_rnti); - } - } else { /* rx_length[i] Max size */ - UE_info->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; - LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + + } else { // end if (UE_id != -1) + LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); } - } else { // end if (UE_id != -1) - LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + }else { + LOG_E(MAC, "[eNB %d/%d] frame %d received a invalid LCID of size %d ( sdu_len %d, lcid %d), dropping packet\n", enb_mod_idP, CC_idP, frameP, - rx_lcids[i], - UE_id); - } + rx_lengths[i], + sdu_lenP,rx_lcids[i]); } break; } - + if((sdu_lenP - (payload_ptr - sduP)) >= rx_lengths[i]){ payload_ptr += rx_lengths[i]; + }else{ + LOG_E(MAC,"[eNB %d/%d] frame %d subframe %d rnti %x sdu_len %d remain_len %d rx_lengths %d\n", + enb_mod_idP,CC_idP,frameP,subframeP,rntiP,sdu_lenP,(uint16_t)(sdu_lenP - (payload_ptr - sduP)), rx_lengths[i]); + return; + } } /* CDRX UL HARQ timers */ @@ -1029,6 +1102,10 @@ parse_ulsch_header(unsigned char *mac_header, tb_length, length, mac_header_ptr - mac_header); + if(num_sdus >= NB_RB_MAX){ + LOG_E(MAC,"parse_ulsch_header: num_sdus(%d) reach max\n",num_sdus); + return NULL; + } rx_lcids[num_sdus] = lcid; rx_lengths[num_sdus] = length; num_sdus++; @@ -1036,6 +1113,10 @@ parse_ulsch_header(unsigned char *mac_header, if (lcid == SHORT_PADDING) { mac_header_ptr++; } else { + if(num_ces >= MAX_NUM_CE){ + LOG_E(MAC,"parse_ulsch_header: num_ces(%d) reach max\n",num_ces); + return NULL; + } rx_ces[num_ces] = lcid; num_ces++; mac_header_ptr++; @@ -1282,6 +1363,7 @@ schedule_ulsch_rnti(module_id_t module_idP, eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc = mac->common_channels; UE_info_t *UE_info = &mac->UE_info; + //uint8_t aggregation = 2; int sched_frame = frameP; @@ -1402,7 +1484,7 @@ schedule_ulsch_rnti(module_id_t module_idP, * This is the normalized RX snr and this should be constant (regardless * of mcs) Is not in dBm, unit from nfapi, converting to dBm */ - const int32_t snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10; + const int32_t snr = UE_sched_ctrl_ptr->pusch_snr[CC_id]; const int32_t target_snr = mac->puSch10xSnr / 10; /* @@ -1560,8 +1642,10 @@ schedule_ulsch_rnti(module_id_t module_idP, UE_template_ptr->cshift[harq_pid] = cshift; /* Setting DCI0 NFAPI struct */ hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[dci_ul_pdu_idx]; + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = UE_template_ptr->pre_first_nb_rb_ul; hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = @@ -1983,7 +2067,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, cqi_req = 0; /* Power control: compute the expected ULSCH RX snr (for the stats) */ /* This is the normalized snr and this should be constant (regardless of mcs) */ - snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10; + snr = UE_sched_ctrl->pusch_snr[CC_id]; target_snr = eNB->puSch10xSnr / 10; /* TODO: target_rx_power was 178, what to put? */ /* This assumes accumulated tpc */ /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 7eccc6222d..1bae590a59 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -469,6 +469,7 @@ typedef struct { #define BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */ + /*! \brief Downlink SCH PDU Structure */ typedef struct { uint8_t payload[8][SCH_PAYLOAD_SIZE_MAX]; @@ -906,6 +907,11 @@ typedef struct { uint32_t pucch_tpc_tx_frame; uint32_t pucch_tpc_tx_subframe; + /// stores the frame where the last bler was calculated + uint32_t pusch_bler_calc_frame; + uint32_t pusch_bler_calc_subframe; + + uint8_t rach_resource_type; uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; @@ -928,6 +934,8 @@ typedef struct { /// Current DL harq round per harq_pid on each CC uint8_t round[NFAPI_CC_MAX][10]; + uint32_t ret_cnt[NFAPI_CC_MAX]; + uint32_t first_cnt[NFAPI_CC_MAX]; /// Current Active TBs per harq_pid on each CC uint8_t tbcnt[NFAPI_CC_MAX][10]; /// Current UL harq round per harq_pid on each CC @@ -937,6 +945,7 @@ typedef struct { unsigned char rballoc_sub_UE[NFAPI_CC_MAX][N_RBG_MAX]; int pre_dci_dl_pdu_idx; uint16_t ta_timer; + double ta_update_f; int16_t ta_update; uint16_t ul_consecutive_errors; int32_t context_active_timer; @@ -954,13 +963,22 @@ typedef struct { int32_t phr_received; uint8_t periodic_ri_received[NFAPI_CC_MAX]; uint8_t aperiodic_ri_received[NFAPI_CC_MAX]; - uint8_t pucch1_cqi_update[NFAPI_CC_MAX]; - uint8_t pucch1_snr[NFAPI_CC_MAX]; - uint8_t pucch2_cqi_update[NFAPI_CC_MAX]; - uint8_t pucch2_snr[NFAPI_CC_MAX]; - uint8_t pucch3_cqi_update[NFAPI_CC_MAX]; - uint8_t pucch3_snr[NFAPI_CC_MAX]; - uint8_t pusch_snr[NFAPI_CC_MAX]; + int16_t pucch1_cqi_update[NFAPI_CC_MAX]; + int16_t pucch1_snr[NFAPI_CC_MAX]; + int16_t pucch2_cqi_update[NFAPI_CC_MAX]; + int16_t pucch2_snr[NFAPI_CC_MAX]; + int16_t pucch3_cqi_update[NFAPI_CC_MAX]; + int16_t pucch3_snr[NFAPI_CC_MAX]; + double pusch_cqi_f[NFAPI_CC_MAX]; + int16_t pusch_cqi[NFAPI_CC_MAX]; + int16_t pusch_snr[NFAPI_CC_MAX]; + int16_t pusch_snr_avg[NFAPI_CC_MAX]; + uint64_t pusch_rx_num[NFAPI_CC_MAX]; + uint64_t pusch_rx_num_old[NFAPI_CC_MAX]; + uint64_t pusch_rx_error_num[NFAPI_CC_MAX]; + uint64_t pusch_rx_error_num_old[NFAPI_CC_MAX]; + double pusch_bler[NFAPI_CC_MAX]; + uint8_t mcs_offset[NFAPI_CC_MAX]; uint16_t feedback_cnt[NFAPI_CC_MAX]; uint16_t timing_advance; uint16_t timing_advance_r9; @@ -1039,6 +1057,7 @@ typedef struct { /// DRX UL retransmission timer, one per UL HARQ process /* Not implemented yet */ /* End of C-DRX related timers */ + uint32_t rlc_out_of_resources_cnt; } UE_sched_ctrl_t; /*! \brief eNB template for the Random access information */ diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index af6d1a7ac3..59554425cc 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -219,7 +219,7 @@ void *mac_enb_task(void *arg) case RRC_MAC_DRX_CONFIG_REQ: LOG_I(MAC, "MAC Task Received RRC_MAC_DRX_CONFIG_REQ\n"); /* Set timers and thresholds values in local MAC context of UE */ - eNB_Config_Local_DRX(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.rrc_mac_drx_config_req); + eNB_Config_Local_DRX(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.rrc_mac_drx_config_req); break; case TERMINATE_MESSAGE: diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c index e8b0593717..2868d94930 100644 --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -44,7 +44,6 @@ #include "common/ran_context.h" -extern FILL_UL_INFO_MUTEX_t fill_ul_mutex; extern void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) { //init as MR @@ -90,16 +89,6 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, UE_mac_inst = NULL; } - // mutex below are used for multiple UE's L2 FAPI simulation. - if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { - pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); - } - LOG_I(MAC, "[MAIN] calling RRC\n"); openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active); diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 6477d60021..bf8202f622 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -69,6 +69,70 @@ int get_rbg_size_last(module_id_t Mod_id, int CC_id) { return RBGsize; } +bool try_allocate_harq_retransmission(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + int UE_id, + int start_rbg, + int *n_rbg_sched, + uint8_t *rbgalloc_mask) { + const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(Mod_id, CC_id); + const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); + UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; + // check whether there are HARQ retransmissions + const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + // retransmission: allocate + const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + if (nb_rb == 0) { + return false; + } + int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; + // needs more RBGs than we can allocate + if (nb_rbg > *n_rbg_sched) { + LOG_D(MAC, + "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", + UE_id, nb_rbg, *n_rbg_sched); + return false; + } + // ensure that the number of RBs can be contained by the RBGs (!), i.e. + // if we allocate the last RBG this one should have the full RBGsize + if ((nb_rb % RBGsize) == 0 && nb_rbg == *n_rbg_sched + && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { + LOG_D(MAC, + "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", + UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); + return false; + } + const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) { // cannot allocate CCE + LOG_D(MAC, "cannot allocate UE %d: no CCE can be allocated\n", UE_id); + return false; + } + ue_ctrl->pre_dci_dl_pdu_idx = idx; + // retransmissions: directly allocate + *n_rbg_sched -= nb_rbg; + ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; + for (; nb_rbg > 0; start_rbg++) { + if (!rbgalloc_mask[start_rbg]) + continue; + ue_ctrl->rballoc_sub_UE[CC_id][start_rbg] = 1; + rbgalloc_mask[start_rbg] = 0; + nb_rbg--; + } + LOG_D(MAC, + "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " + "retx nb_rb %d pre_nb_available_rbs %d\n", + frame, subframe, *n_rbg_sched, UE_id, + UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], + ue_ctrl->pre_nb_available_rbs[CC_id]); + return true; +} + void *rr_dl_setup(void) { void *data = malloc(sizeof(int)); *(int *) data = 0; @@ -115,64 +179,25 @@ int rr_dl_run(module_id_t Mod_id, const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; - if (round != 8) { // retransmission: allocate - const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - if (nb_rb == 0) - goto skip_ue; - int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; - // needs more RBGs than we can allocate - if (nb_rbg > n_rbg_sched) { - LOG_D(MAC, - "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", - UE_id, nb_rbg, n_rbg_sched); - goto skip_ue; + if (round != 8) { + bool r = try_allocate_harq_retransmission(Mod_id, CC_id, frame, subframe, + UE_id, rbg, &n_rbg_sched, + rbgalloc_mask); + if (r) { + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - // ensure that the number of RBs can be contained by the RBGs (!), i.e. - // if we allocate the last RBG this one should have the full RBGsize - if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched - && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { - LOG_D(MAC, - "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", - UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); - goto skip_ue; - } - const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; - const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); - if (idx < 0) - goto skip_ue; // cannot allocate CCE - ue_ctrl->pre_dci_dl_pdu_idx = idx; - // retransmissions: directly allocate - n_rbg_sched -= nb_rbg; - ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; - for (; nb_rbg > 0; rbg++) { - if (!rbgalloc_mask[rbg]) - continue; - ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; - rbgalloc_mask[rbg] = 0; - nb_rbg--; - } - LOG_D(MAC, - "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " - "round %d retx nb_rb %d pre_nb_available_rbs %d\n", - frame, subframe, n_rbg_sched, UE_id, round, - UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], - ue_ctrl->pre_nb_available_rbs[CC_id]); - /* if there are no more RBG to give, return */ - if (n_rbg_sched <= 0) - return 0; - max_num_ue--; - /* if there are no UEs that can be allocated anymore, return */ - if (max_num_ue == 0) - return n_rbg_sched; - for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) { *cur_UE = UE_id; cur_UE = &UE_sched.next[UE_id]; } } - -skip_ue: UE_id = next_ue_list_looped(UE_list, UE_id); } while (UE_id != *start_ue); *cur_UE = -1; // mark end @@ -187,11 +212,12 @@ skip_ue: cur_UE = &UE_sched.head; while (*cur_UE >= 0 && max_num_ue > 0) { const int UE_id = *cur_UE; - cur_UE = &UE_sched.next[UE_id]; // go to next const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) { LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id); + // SKIP this UE in the list by marking the next as the current + *cur_UE = UE_sched.next[UE_id]; continue; } UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; @@ -200,6 +226,7 @@ skip_ue: const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total; rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize); max_num_ue--; + cur_UE = &UE_sched.next[UE_id]; // go to next } *cur_UE = -1; // not all UEs might be allocated, mark end @@ -284,56 +311,19 @@ int pf_wbcqi_dl_run(module_id_t Mod_id, const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; - if (round != 8) { // retransmission: allocate - const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - if (nb_rb == 0) - continue; - int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; - // needs more RBGs than we can allocate - if (nb_rbg > n_rbg_sched) { - LOG_D(MAC, - "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", - UE_id, nb_rbg, n_rbg_sched); - continue; + if (round != 8) { + bool r = try_allocate_harq_retransmission(Mod_id, CC_id, frame, subframe, + UE_id, rbg, &n_rbg_sched, + rbgalloc_mask); + if (r) { + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - // ensure that the number of RBs can be contained by the RBGs (!), i.e. - // if we allocate the last RBG this one should have the full RBGsize - if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched - && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { - LOG_D(MAC, - "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", - UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); - continue; - } - const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; - const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); - if (idx < 0) - continue; // cannot allocate CCE - ue_ctrl->pre_dci_dl_pdu_idx = idx; - // retransmissions: directly allocate - n_rbg_sched -= nb_rbg; - ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; - for (; nb_rbg > 0; rbg++) { - if (!rbgalloc_mask[rbg]) - continue; - ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; - rbgalloc_mask[rbg] = 0; - nb_rbg--; - } - LOG_D(MAC, - "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " - "round %d retx nb_rb %d pre_nb_available_rbs %d\n", - frame, subframe, n_rbg_sched, UE_id, round, - UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], - ue_ctrl->pre_nb_available_rbs[CC_id]); - /* if there are no more RBG to give, return */ - if (n_rbg_sched <= 0) - return 0; - max_num_ue--; - /* if there are no UEs that can be allocated anymore, return */ - if (max_num_ue == 0) - return n_rbg_sched; - for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0) continue; @@ -436,56 +426,19 @@ int mt_wbcqi_dl_run(module_id_t Mod_id, const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; - if (round != 8) { // retransmission: allocate - const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - if (nb_rb == 0) - continue; - int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; - // needs more RBGs than we can allocate - if (nb_rbg > n_rbg_sched) { - LOG_D(MAC, - "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", - UE_id, nb_rbg, n_rbg_sched); - continue; + if (round != 8) { + bool r = try_allocate_harq_retransmission(Mod_id, CC_id, frame, subframe, + UE_id, rbg, &n_rbg_sched, + rbgalloc_mask); + if (r) { + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - // ensure that the number of RBs can be contained by the RBGs (!), i.e. - // if we allocate the last RBG this one should have the full RBGsize - if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched - && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { - LOG_D(MAC, - "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", - UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); - continue; - } - const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; - const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); - if (idx < 0) - continue; // cannot allocate CCE - ue_ctrl->pre_dci_dl_pdu_idx = idx; - // retransmissions: directly allocate - n_rbg_sched -= nb_rbg; - ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; - for (; nb_rbg > 0; rbg++) { - if (!rbgalloc_mask[rbg]) - continue; - ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; - rbgalloc_mask[rbg] = 0; - nb_rbg--; - } - LOG_D(MAC, - "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " - "round %d retx nb_rb %d pre_nb_available_rbs %d\n", - frame, subframe, n_rbg_sched, UE_id, round, - UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], - ue_ctrl->pre_nb_available_rbs[CC_id]); - /* if there are no more RBG to give, return */ - if (n_rbg_sched <= 0) - return 0; - max_num_ue--; - /* if there are no UEs that can be allocated anymore, return */ - if (max_num_ue == 0) - return n_rbg_sched; - for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0) continue; @@ -781,7 +734,7 @@ void calculate_max_mcs_min_rb(module_id_t mod_id, /* find maximum MCS */ while ((phr - *tx_power < 0 || tbs > bytes) && *mcs > 3) { - mcs--; + (*mcs)--; tbs = get_TBS_UL(*mcs, rb_table[*rb_index]); *tx_power = estimate_ue_tx_power(tbs * 8, rb_table[*rb_index], 0, Ncp, 0); } @@ -942,7 +895,10 @@ int rr_ul_run(module_id_t Mod_id, &tx_power); UE_template->pre_assigned_mcs_ul = mcs; - rb_idx_required[UE_id] = rb_table_index; + /* rb_idx_given >= 22: apparently the PHY cannot support more than 48 + * RBs in the uplink. Hence, we limit every UE to 48 RBs, which is at + * index 22 */ + rb_idx_required[UE_id] = min(22, rb_table_index); //UE_template->pre_allocated_nb_rb_ul = rb_table[rb_table_index]; /* only print log when PHR changed */ static int phr = 0; diff --git a/openair2/LAYER2/MAC/slicing/slicing.c b/openair2/LAYER2/MAC/slicing/slicing.c index 9c88f6cffb..48dd99afeb 100644 --- a/openair2/LAYER2/MAC/slicing/slicing.c +++ b/openair2/LAYER2/MAC/slicing/slicing.c @@ -336,6 +336,8 @@ void static_dl(module_id_t mod_id, rbgalloc_slice_mask[rbg] = rbgalloc_mask[rbg]; n_rbg_sched += rbgalloc_mask[rbg]; } + if (n_rbg_sched == 0) /* no free RBGs, e.g., taken by RA */ + continue; s->s[i]->dl_algo.run(mod_id, CC_id, @@ -445,6 +447,8 @@ void static_ul(module_id_t mod_id, } if (!last_rb_blocked) rbs[n_contig - 1].length = p->posHigh - rbs[n_contig - 1].start + 1; + if (n_contig == 1 && rbs[0].length == 0) /* no RBs, e.g., taken by RA */ + continue; s->s[i]->ul_algo.run(mod_id, CC_id, diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index e97f1bebdd..0dedacb11f 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -3064,8 +3064,8 @@ ue_scheduler(const module_id_t module_idP, switch (ITTI_MSG_ID(msg_p)) { case RRC_MAC_CCCH_DATA_REQ: LOG_I(MAC, - "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", - ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p), + "Received %s from %s: instance %ld, frameP %d, eNB_index %d\n", + ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_DESTINATION_INSTANCE(msg_p), RRC_MAC_CCCH_DATA_REQ(msg_p).frame, RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index); // TODO process CCCH data req. @@ -3099,6 +3099,9 @@ ue_scheduler(const module_id_t module_idP, } } + void rlc_tick(int, int); + rlc_tick(rxFrameP % 1024, rxSubframeP); + //#endif UE_mac_inst[module_idP].txFrame = txFrameP; UE_mac_inst[module_idP].txSubframe = txSubframeP; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c index 30dccea2a9..452ed45b3a 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_compute_tbs_common.c @@ -82,8 +82,11 @@ uint32_t nr_compute_tbs(uint16_t Qm, } } } - //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); + + LOG_D(PHY, "In %s: Ninfo %d nbp_re %d nb_re %d Qm %d, R %d, tbs %d\n", __FUNCTION__, Ninfo, nbp_re, nb_re, Qm, R, nr_tbs); + return nr_tbs; + } diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index d8583167dd..381dce11b2 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -20,7 +20,7 @@ */ /* \file nr_mac.h - * \brief common MAC data structures, constant, and function prototype + * \brief common MAC data structures and constants * \author R. Knopp, K.H. HSU, G. Casati * \date 2019 * \version 0.1 @@ -37,13 +37,30 @@ #include #include +#define TABLE_38213_13_1_NUM_INDEXES 15 +#define TABLE_38213_13_2_NUM_INDEXES 14 +#define TABLE_38213_13_3_NUM_INDEXES 9 +#define TABLE_38213_13_4_NUM_INDEXES 16 +#define TABLE_38213_13_5_NUM_INDEXES 9 +#define TABLE_38213_13_6_NUM_INDEXES 10 +#define TABLE_38213_13_7_NUM_INDEXES 12 +#define TABLE_38213_13_8_NUM_INDEXES 8 +#define TABLE_38213_13_9_NUM_INDEXES 4 +#define TABLE_38213_13_10_NUM_INDEXES 8 +#define TABLE_38213_13_11_NUM_INDEXES 16 +#define TABLE_38213_13_12_NUM_INDEXES 14 + +// Definitions for MAC control and data #define NR_BCCH_DL_SCH 3 // SI - #define NR_BCCH_BCH 5 // MIB - #define CCCH_PAYLOAD_SIZE_MAX 128 - #define RAR_PAYLOAD_SIZE_MAX 128 +#define MAX_BWP_SIZE 275 + +typedef enum frequency_range_e { + FR1 = 0, + FR2 +} frequency_range_t; // For both DL/UL-SCH // Except: @@ -102,22 +119,22 @@ typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED; // Long BSR for all logical channel group ID typedef struct { - uint8_t Buffer_size7: 8; - uint8_t Buffer_size6: 8; - uint8_t Buffer_size5: 8; - uint8_t Buffer_size4: 8; - uint8_t Buffer_size3: 8; - uint8_t Buffer_size2: 8; - uint8_t Buffer_size1: 8; - uint8_t Buffer_size0: 8; - uint8_t LcgID0: 1; - uint8_t LcgID1: 1; - uint8_t LcgID2: 1; - uint8_t LcgID3: 1; - uint8_t LcgID4: 1; - uint8_t LcgID5: 1; - uint8_t LcgID6: 1; - uint8_t LcgID7: 1; + uint8_t LcgID0: 1; // octet 1 [0] + uint8_t LcgID1: 1; // octet 1 [1] + uint8_t LcgID2: 1; // octet 1 [2] + uint8_t LcgID3: 1; // octet 1 [3] + uint8_t LcgID4: 1; // octet 1 [4] + uint8_t LcgID5: 1; // octet 1 [5] + uint8_t LcgID6: 1; // octet 1 [6] + uint8_t LcgID7: 1; // octet 1 [7] + uint8_t Buffer_size0: 8; // octet 2 [7:0] + uint8_t Buffer_size1: 8; // octet 3 [7:0] + uint8_t Buffer_size2: 8; // octet 4 [7:0] + uint8_t Buffer_size3: 8; // octet 5 [7:0] + uint8_t Buffer_size4: 8; // octet 6 [7:0] + uint8_t Buffer_size5: 8; // octet 7 [7:0] + uint8_t Buffer_size6: 8; // octet 8 [7:0] + uint8_t Buffer_size7: 8; // octet 9 [7:0] } __attribute__ ((__packed__)) NR_BSR_LONG; typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED; @@ -339,6 +356,113 @@ typedef struct { #define NR_MAX_NUM_LCGID 8 #define MAX_RLC_SDU_SUBHEADER_SIZE 3 +//=========== +// PRACH defs +//=========== + +// =============================================== +// SSB to RO mapping public defines and structures +// =============================================== +#define MAX_SSB_PER_RO (16) // Maximum number of SSBs that can be mapped to a single RO +#define MAX_TDM (7) // Maximum nb of PRACH occasions TDMed in a slot +#define MAX_FDM (8) // Maximum nb of PRACH occasions FDMed in a slot + +// PRACH occasion details +typedef struct prach_occasion_info { + uint8_t start_symbol; // 0 - 13 (14 symbols in a slot) + uint8_t fdm; // 0-7 (possible values of msg1-FDM: 1, 2, 4 or 8) + uint8_t slot; // 0 - 159 (maximum number of slots in a 10ms frame - @ 240kHz) + uint8_t frame; // 0 - 15 (maximum number of frames in a 160ms association pattern) + uint8_t mapped_ssb_idx[MAX_SSB_PER_RO]; // List of mapped SSBs + uint8_t nb_mapped_ssb; + uint16_t format; // RO preamble format +} prach_occasion_info_t; + +// PRACH occasion slot details +// A PRACH occasion slot is a series of PRACH occasions in time (symbols) and frequency +typedef struct prach_occasion_slot { + prach_occasion_info_t prach_occasion[MAX_TDM][MAX_FDM]; // Starting symbol of each PRACH occasions in a slot + uint8_t nb_of_prach_occasion_in_time; + uint8_t nb_of_prach_occasion_in_freq; +} prach_occasion_slot_t; + +//========= +// DCI defs +//========= + +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_MCS_C, +} nr_rnti_type_t; + +typedef enum subcarrier_spacing_e { + scs_15kHz = 0x1, + scs_30kHz = 0x2, + scs_60kHz = 0x4, + scs_120kHz = 0x8, + scs_240kHz = 0x16 +} subcarrier_spacing_t; + +typedef enum channel_bandwidth_e { + bw_5MHz = 0x1, + bw_10MHz = 0x2, + bw_20MHz = 0x4, + bw_40MHz = 0x8, + bw_80MHz = 0x16, + bw_100MHz = 0x32 +} channel_bandwidth_t; + +typedef enum nr_ssb_and_cset_mux_pattern_type_e { + NR_SSB_AND_CSET_MUX_PATTERN_TYPE1=1, + NR_SSB_AND_CSET_MUX_PATTERN_TYPE2, + NR_SSB_AND_CSET_MUX_PATTERN_TYPE3 +} nr_ssb_and_cset_mux_pattern_type_t; + +typedef enum { + SFN_C_MOD_2_EQ_0, + SFN_C_MOD_2_EQ_1, + SFN_C_IMPOSSIBLE +} SFN_C_TYPE; + +typedef struct Type0_PDCCH_CSS_config_s { + int32_t num_rbs; + int32_t num_symbols; + int32_t rb_offset; // Offset from SSB RB0 + uint32_t type0_pdcch_ss_mux_pattern; + uint16_t frame; + SFN_C_TYPE sfn_c; + uint32_t n_c; + uint32_t n_0; + uint32_t number_of_search_space_per_slot; + uint32_t first_symbol_index; + uint32_t search_space_duration; + uint32_t ssb_length; + uint32_t ssb_index; + uint32_t cset_start_rb; +} NR_Type0_PDCCH_CSS_config_t; #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 8fe83dd40d..8dc261df1d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -33,6 +33,8 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include +#define reserved 0xffff + const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160}; // Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz @@ -48,8 +50,75 @@ uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,8 // Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3} uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69}; -const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"}; -const char *prachfmt03[]={"0","1","2","3"}; + +// specification mapping talbe, table_38$x_$y_$z_c$a +// - $x: specification +// - $y: subclause-major +// - $z: subclause-minor +// - $a: ($a)th of column in table, start from zero +const int32_t table_38213_13_1_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, reserved}; // index 15 reserved +const int32_t table_38213_13_1_c2[16] = {24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 96, 96, 96, reserved}; // index 15 reserved +const int32_t table_38213_13_1_c3[16] = { 2, 2, 2, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved}; // index 15 reserved +const int32_t table_38213_13_1_c4[16] = { 0, 2, 4, 0, 2, 4, 12, 16, 12, 16, 12, 16, 38, 38, 38, reserved}; // index 15 reserved + +const int32_t table_38213_13_2_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved}; // index 14-15 reserved +const int32_t table_38213_13_2_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved}; // index 14-15 reserved +const int32_t table_38213_13_2_c3[16] = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved}; // index 14-15 reserved +const int32_t table_38213_13_2_c4[16] = { 5, 6, 7, 8, 5, 6, 7, 8, 18, 20, 18, 20, 18, 20, reserved, reserved}; // index 14-15 reserved + +const int32_t table_38213_13_3_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_3_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_3_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_3_c4[16] = { 2, 6, 2, 6, 2, 6, 28, 28, 28, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved + +const int32_t table_38213_13_4_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +const int32_t table_38213_13_4_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48}; +const int32_t table_38213_13_4_c3[16] = { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2}; +const int32_t table_38213_13_4_c4[16] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 12, 14, 16, 12, 14, 16}; + +const int32_t table_38213_13_5_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_5_c2[16] = {48, 48, 48, 96, 96, 96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_5_c3[16] = { 1, 2, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const int32_t table_38213_13_5_c4[16] = { 4, 4, 4, 0, 56, 0, 56, 0, 56, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved + +const int32_t table_38213_13_6_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved +const int32_t table_38213_13_6_c2[16] = {24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved +const int32_t table_38213_13_6_c3[16] = { 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved +const int32_t table_38213_13_6_c4[16] = { 0, 4, 0, 4, 0, 28, 0, 28, 0, 28, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved + +const int32_t table_38213_13_7_c1[16] = {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, reserved, reserved, reserved, reserved}; // index 12-15 reserved +const int32_t table_38213_13_7_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 48, 48, 96, 96, reserved, reserved, reserved, reserved}; // index 12-15 reserved +const int32_t table_38213_13_7_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved}; // index 12-15 reserved +const int32_t table_38213_13_7_c4[16] = { 0, 8, 0, 8, 0, 8, 28, 28,-41, 49,-41, 97, reserved, reserved, reserved, reserved}; // index 12-15 reserved, condition A as default + +const int32_t table_38213_13_8_c1[16] = { 1, 1, 1, 1, 3, 3, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved +const int32_t table_38213_13_8_c2[16] = {24, 24, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved +const int32_t table_38213_13_8_c3[16] = { 2, 2, 1, 2, 2, 2, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved +const int32_t table_38213_13_8_c4[16] = { 0, 4, 14, 14,-20, 24,-20, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved, condition A as default + +const int32_t table_38213_13_9_c1[16] = {1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved +const int32_t table_38213_13_9_c2[16] = {96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved +const int32_t table_38213_13_9_c3[16] = { 1, 1, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved +const int32_t table_38213_13_9_c4[16] = { 0, 16, 0, 16, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved + +const int32_t table_38213_13_10_c1[16] = {1, 1, 1, 1, 2, 2, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved +const int32_t table_38213_13_10_c2[16] = {48, 48, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved +const int32_t table_38213_13_10_c3[16] = { 1, 1, 2, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved +const int32_t table_38213_13_10_c4[16] = { 0, 8, 0, 8,-41, 25,-41, 49, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved, condition A as default + +const float table_38213_13_11_c1[16] = { 0, 0, 2, 2, 5, 5, 7, 7, 0, 5, 0, 0, 2, 2, 5, 5}; // O +const int32_t table_38213_13_11_c2[16] = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1}; +const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 1, 1, 1, 1, 1, 1, 1}; // M +const int32_t table_38213_13_11_c4[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2}; // i is even as default + +const float table_38213_13_12_c1[16] = { 0, 0, 2.5f, 2.5f, 5, 5, 0, 2.5f, 5, 7.5f, 7.5f, 7.5f, 0, 5, reserved, reserved}; // O, index 14-15 reserved +const int32_t table_38213_13_12_c2[16] = { 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, reserved, reserved}; // index 14-15 reserved +const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 1, reserved, reserved}; // M, index 14-15 reserved + +const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 }; + +const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"}; +const char *duplex_mode[]={"FDD","TDD"}; uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) { @@ -86,100 +155,164 @@ uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) } } +//38.211 Table 6.3.3.2-1 +int16_t table_6_3_3_2_1[16][5] = { +//Length_RA, delta_f_RA_PRACH, delta_f_PUSCH, N_RA_RB, kbar +{ 839, 1.25, 15, 6, 7}, +{ 839, 1.25, 30, 3, 1}, +{ 839, 1.25, 60, 2, 133}, +{ 839, 5, 15, 24, 12}, +{ 839, 5, 30, 12, 10}, +{ 839, 5, 60, 6, 7}, +{ 139, 15, 15, 12, 2}, +{ 139, 15, 30, 6, 2}, +{ 139, 15, 60, 3, 2}, +{ 139, 30, 15, 24, 2}, +{ 139, 30, 30, 12, 2}, +{ 139, 30, 60, 6, 2}, +{ 139, 60, 60, 12, 2}, +{ 139, 60, 120, 6, 2}, +{ 139, 120, 60, 24, 2}, +{ 139, 120, 120, 12, 2} +}; +/* Function to get number of RBs required for prach occasion based on + * 38.211 Table 6.3.3.2-1 */ +int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH) { + + int8_t index = 0; + switch(delta_f_RA_PRACH) { + case 0 : index = 6; + if (delta_f_PUSCH == 0) + index += 0; + else if(delta_f_PUSCH == 1) + index += 1; + else + index += 2; + break; + + case 1 : index = 9; + if (delta_f_PUSCH == 0) + index += 0; + else if(delta_f_PUSCH == 1) + index += 1; + else + index += 2; + break; + + case 2 : index = 11; + if (delta_f_PUSCH == 2) + index += 0; + else + index += 1; + break; + + case 3: index = 13; + if (delta_f_PUSCH == 2) + index += 0; + else + index += 1; + break; + + default : index = 10;/*30khz prach scs and 30khz pusch scs*/ + + } + + return table_6_3_3_2_1[index][3]; +} // Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink // the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent. // E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9. // E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6 int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = { //format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 -{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 -{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 -{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9 -{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 -{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 -{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 -{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 -{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 -{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 16, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 16, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 16, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 8, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 8, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 8, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 4, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 4, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 4, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 4, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 2, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 2, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 2, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 2, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{0, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{0, -1, 1, 0, 16, 0, 1, 1, 0}, // (subframe number) 4 +{0, -1, 1, 0, 128, 0, 1, 1, 0}, // (subframe number) 7 +{0, -1, 1, 0, 66, 0, 1, 1, 0}, // (subframe number) 1,6 +{0, -1, 1, 0, 132, 0, 1, 1, 0}, // (subframe number) 2,7 +{0, -1, 1, 0, 264, 0, 1, 1, 0}, // (subframe number) 3,8 +{0, -1, 1, 0, 146, 0, 1, 1, 0}, // (subframe number) 1,4,7 +{0, -1, 1, 0, 292, 0, 1, 1, 0}, // (subframe number) 2,5,8 +{0, -1, 1, 0, 584, 0, 1, 1, 0}, // (subframe number) 3, 6, 9 +{0, -1, 1, 0, 341, 0, 1, 1, 0}, // (subframe number) 0,2,4,6,8 +{0, -1, 1, 0, 682, 0, 1, 1, 0}, // (subframe number) 1,3,5,7,9 +{0, -1, 1, 0, 1023, 0, 1, 1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{1, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 16, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 16, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 16, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 8, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 8, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 8, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 4, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 4, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 4, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 4, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 2, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 2, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 2, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 2, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{1, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{1, -1, 1, 0, 16, 0, 1, 1, 0}, // (subframe number) 4 +{1, -1, 1, 0, 128, 0, 1, 1, 0}, // (subframe number) 7 +{1, -1, 1, 0, 66, 0, 1, 1, 0}, // (subframe number) 1,6 +{1, -1, 1, 0, 132, 0, 1, 1, 0}, // (subframe number) 2,7 +{1, -1, 1, 0, 264, 0, 1, 1, 0}, // (subframe number) 3,8 +{1, -1, 1, 0, 146, 0, 1, 1, 0}, // (subframe number) 1,4,7 +{1, -1, 1, 0, 292, 0, 1, 1, 0}, // (subframe number) 2,5,8 +{1, -1, 1, 0, 584, 0, 1, 1, 0}, // (subframe number) 3,6,9 +{2, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 4, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 2, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 2, 0, 32, 0, 1, 1, 0}, // (subframe number) 5 +{2, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{2, -1, 1, 0, 32, 0, 1, 1, 0}, // (subframe number) 5 +{3, -1, 16, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 16, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 16, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 16, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{3, -1, 8, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 8, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 8, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 4, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 4, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 4, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 4, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{3, -1, 2, 1, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 2, 1, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 2, 1, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 2, 1, 512, 0, 1, 1, 0}, // (subframe number) 9 +{3, -1, 1, 0, 2, 0, 1, 1, 0}, // (subframe number) 1 +{3, -1, 1, 0, 16, 0, 1, 1, 0}, // (subframe number) 4 +{3, -1, 1, 0, 128, 0, 1, 1, 0}, // (subframe number) 7 +{3, -1, 1, 0, 66, 0, 1, 1, 0}, // (subframe number) 1,6 +{3, -1, 1, 0, 132, 0, 1, 1, 0}, // (subframe number) 2,7 +{3, -1, 1, 0, 264, 0, 1, 1, 0}, // (subframe number) 3,8 +{3, -1, 1, 0, 146, 0, 1, 1, 0}, // (subframe number) 1,4,7 +{3, -1, 1, 0, 292, 0, 1, 1, 0}, // (subframe number) 2,5,8 +{3, -1, 1, 0, 584, 0, 1, 1, 0}, // (subframe number) 3, 6, 9 +{3, -1, 1, 0, 341, 0, 1, 1, 0}, // (subframe number) 0,2,4,6,8 +{3, -1, 1, 0, 682, 0, 1, 1, 0}, // (subframe number) 1,3,5,7,9 +{3, -1, 1, 0, 1023, 0, 1, 1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 {0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 {0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4 {0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 @@ -353,73 +486,73 @@ int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = { // Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = { //format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) -{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) -{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) -{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) -{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) -{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) -{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) -{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) -{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) -{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) -{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) -{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) -{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) -{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) -{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) -{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9) -{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) -{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) -{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6) -{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6) -{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6) -{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) -{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) -{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) -{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) -{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) -{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) -{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) -{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) -{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) -{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) -{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) -{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) -{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) -{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) -{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) -{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) -{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) +{0, -1, 16, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 8, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 4, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 2, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 2, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 2, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{0, -1, 2, 1, 16, 0, 1, 1, 0}, // (subrame number 4) +{0, -1, 1, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{0, -1, 1, 0, 256, 0, 1, 1, 0}, // (subrame number 8) +{0, -1, 1, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{0, -1, 1, 0, 64, 0, 1, 1, 0}, // (subrame number 6) +{0, -1, 1, 0, 32, 0, 1, 1, 0}, // (subrame number 5) +{0, -1, 1, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{0, -1, 1, 0, 8, 0, 1, 1, 0}, // (subrame number 3) +{0, -1, 1, 0, 4, 0, 1, 1, 0}, // (subrame number 2) +{0, -1, 1, 0, 66, 0, 1, 1, 0}, // (subrame number 1,6) +{0, -1, 1, 0, 66, 7, 1, 1, 0}, // (subrame number 1,6) +{0, -1, 1, 0, 528, 0, 1, 1, 0}, // (subrame number 4,9) +{0, -1, 1, 0, 264, 0, 1, 1, 0}, // (subrame number 3,8) +{0, -1, 1, 0, 132, 0, 1, 1, 0}, // (subrame number 2,7) +{0, -1, 1, 0, 768, 0, 1, 1, 0}, // (subrame number 8,9) +{0, -1, 1, 0, 784, 0, 1, 1, 0}, // (subrame number 4,8,9) +{0, -1, 1, 0, 536, 0, 1, 1, 0}, // (subrame number 3,4,9) +{0, -1, 1, 0, 896, 0, 1, 1, 0}, // (subrame number 7,8,9) +{0, -1, 1, 0, 792, 0, 1, 1, 0}, // (subrame number 3,4,8,9) +{0, -1, 1, 0, 960, 0, 1, 1, 0}, // (subrame number 6,7,8,9) +{0, -1, 1, 0, 594, 0, 1, 1, 0}, // (subrame number 1,4,6,9) +{0, -1, 1, 0, 682, 0, 1, 1, 0}, // (subrame number 1,3,5,7,9) +{1, -1, 16, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 8, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 4, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 2, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 2, 1, 128, 0, 1, 1, 0}, // (subrame number 7) +{1, -1, 1, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{2, -1, 16, 1, 64, 0, 1, 1, 0}, // (subrame number 6) +{2, -1, 8, 1, 64, 0, 1, 1, 0}, // (subrame number 6) +{2, -1, 4, 1, 64, 0, 1, 1, 0}, // (subrame number 6) +{2, -1, 2, 0, 64, 7, 1, 1, 0}, // (subrame number 6) +{2, -1, 2, 1, 64, 7, 1, 1, 0}, // (subrame number 6) +{2, -1, 1, 0, 64, 7, 1, 1, 0}, // (subrame number 6) +{3, -1, 16, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 8, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 4, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 2, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 2, 1, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 2, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{3, -1, 2, 1, 16, 0, 1, 1, 0}, // (subrame number 4) +{3, -1, 1, 0, 512, 0, 1, 1, 0}, // (subrame number 9) +{3, -1, 1, 0, 256, 0, 1, 1, 0}, // (subrame number 8) +{3, -1, 1, 0, 128, 0, 1, 1, 0}, // (subrame number 7) +{3, -1, 1, 0, 64, 0, 1, 1, 0}, // (subrame number 6) +{3, -1, 1, 0, 32, 0, 1, 1, 0}, // (subrame number 5) +{3, -1, 1, 0, 16, 0, 1, 1, 0}, // (subrame number 4) +{3, -1, 1, 0, 8, 0, 1, 1, 0}, // (subrame number 3) +{3, -1, 1, 0, 4, 0, 1, 1, 0}, // (subrame number 2) +{3, -1, 1, 0, 66, 0, 1, 1, 0}, // (subrame number 1,6) +{3, -1, 1, 0, 66, 7, 1, 1, 0}, // (subrame number 1,6) +{3, -1, 1, 0, 528, 0, 1, 1, 0}, // (subrame number 4,9) +{3, -1, 1, 0, 264, 0, 1, 1, 0}, // (subrame number 3,8) +{3, -1, 1, 0, 132, 0, 1, 1, 0}, // (subrame number 2,7) +{3, -1, 1, 0, 768, 0, 1, 1, 0}, // (subrame number 8,9) +{3, -1, 1, 0, 784, 0, 1, 1, 0}, // (subrame number 4,8,9) +{3, -1, 1, 0, 536, 0, 1, 1, 0}, // (subrame number 3,4,9) +{3, -1, 1, 0, 896, 0, 1, 1, 0}, // (subrame number 7,8,9) +{3, -1, 1, 0, 792, 0, 1, 1, 0}, // (subrame number 3,4,8,9) +{3, -1, 1, 0, 594, 0, 1, 1, 0}, // (subrame number 1,4,6,9) +{3, -1, 1, 0, 682, 0, 1, 1, 0}, // (subrame number 1,3,5,7,9) {0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9) {0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9) {0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9) @@ -873,17 +1006,70 @@ int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = { int get_format0(uint8_t index, - uint8_t unpaired){ + uint8_t unpaired, + frequency_range_t frequency_range){ uint16_t format; - if (unpaired) - format = table_6_3_3_2_3_prachConfig_Index[index][0]; - else - format = table_6_3_3_2_2_prachConfig_Index[index][0]; - + if (unpaired) { + if (frequency_range==FR1) + format = table_6_3_3_2_3_prachConfig_Index[index][0]; + else + format = table_6_3_3_2_4_prachConfig_Index[index][0]; + } + else { + if (frequency_range==FR1) + format = table_6_3_3_2_2_prachConfig_Index[index][0]; + else + AssertFatal(0==1,"no paired spectrum for FR2\n"); + } return format; } +int64_t *get_prach_config_info(uint32_t pointa, + uint8_t index, + uint8_t unpaired) { + int64_t *prach_config_info_p; + + if (pointa > 2016666) { //FR2 + prach_config_info_p = table_6_3_3_2_4_prachConfig_Index[index]; + } + else { // FR1 + if (unpaired) + prach_config_info_p = table_6_3_3_2_3_prachConfig_Index[index]; + else + prach_config_info_p = table_6_3_3_2_2_prachConfig_Index[index]; + } // FR2 / FR1 + + return prach_config_info_p; +} + +void find_aggregation_candidates(uint8_t *aggregation_level, + uint8_t *nr_of_candidates, + NR_SearchSpace_t *ss) { + + if (ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0) { + *aggregation_level = 1; + *nr_of_candidates = ss->nrofCandidates->aggregationLevel1; + } + if (ss->nrofCandidates->aggregationLevel2 != NR_SearchSpace__nrofCandidates__aggregationLevel2_n0) { + *aggregation_level = 2; + *nr_of_candidates = ss->nrofCandidates->aggregationLevel2; + } + if (ss->nrofCandidates->aggregationLevel4 != NR_SearchSpace__nrofCandidates__aggregationLevel4_n0) { + *aggregation_level = 4; + *nr_of_candidates = ss->nrofCandidates->aggregationLevel4; + } + if (ss->nrofCandidates->aggregationLevel8 != NR_SearchSpace__nrofCandidates__aggregationLevel8_n0) { + *aggregation_level = 8; + *nr_of_candidates = ss->nrofCandidates->aggregationLevel8; + } + if (ss->nrofCandidates->aggregationLevel16 != NR_SearchSpace__nrofCandidates__aggregationLevel16_n0) { + *aggregation_level = 16; + *nr_of_candidates = ss->nrofCandidates->aggregationLevel16; + } +} + + void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset) { @@ -955,6 +1141,162 @@ void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, } } +int get_nr_prach_occasion_info_from_index(uint8_t index, + uint32_t pointa, + uint8_t mu, + uint8_t unpaired, + uint16_t *format, + uint8_t *start_symbol, + uint8_t *N_t_slot, + uint8_t *N_dur, + uint8_t *N_RA_slot, + uint16_t *N_RA_sfn, + uint8_t *max_association_period) { + + int x; + int64_t s_map; + uint8_t format2 = 0xff; + if (pointa > 2016666) { //FR2 + x = table_6_3_3_2_4_prachConfig_Index[index][2]; + s_map = table_6_3_3_2_4_prachConfig_Index[index][5]; + for(int i = 0; i < 64 ;i++) { + if ( (s_map >> i) & 0x01) { + (*N_RA_sfn)++; + } + } + *N_RA_slot = table_6_3_3_2_4_prachConfig_Index[index][7]; // Number of RACH slots within a subframe + *max_association_period = 160/(x * 10); + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6];//multiple prach occasions in diff slot + *N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8]; + *N_dur = table_6_3_3_2_4_prachConfig_Index[index][9]; + if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1) + format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1]; + + *format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8); + LOG_D(MAC,"Getting Total PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_sfn = %u\n", + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur, + *N_RA_sfn); + } + return 1; + } + else { + + if (unpaired) { + x = table_6_3_3_2_3_prachConfig_Index[index][2]; + s_map = table_6_3_3_2_3_prachConfig_Index[index][4]; + for(int i = 0; i < 64 ;i++) { + if ( (s_map >> i) & 0x01) { + (*N_RA_sfn)++; + } + } + *N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe + *max_association_period = 160/(x * 10); + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5]; + *N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7]; + *N_dur = table_6_3_3_2_3_prachConfig_Index[index][8]; + if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1) + format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1]; + *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8); + LOG_I(MAC,"Getting Total PRACH info from index %d (col %lu ) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_sfn = %u\n", + index, table_6_3_3_2_3_prachConfig_Index[index][6], + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur, + *N_RA_sfn); + } + return 1; + } + else { // FDD + x = table_6_3_3_2_2_prachConfig_Index[index][2]; + s_map = table_6_3_3_2_2_prachConfig_Index[index][4]; + *N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6]; + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5]; + *N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7]; + *N_dur = table_6_3_3_2_2_prachConfig_Index[index][8]; + if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1) + format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1]; + *format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8); + LOG_D(MAC,"Getting Total PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur); + } + return 1; + } + } +} + + +uint8_t get_nr_prach_duration(uint8_t prach_format){ + + switch(prach_format){ + + case 0: // format 0 + return 0; + + case 1: // format 1 + return 0; + + case 2: // format 2 + return 0; + + case 3: // format 3 + return 0; + + case 4: // format A1 + return 2; + + case 5: // format A2 + return 4; + + case 6: // format A3 + return 6; + + case 7: // format B1 + return 2; + + case 8: // format B4 + return 12; + + case 9: // format C0 + return 2; + + case 10: // format C2 + return 6; + + case 11: // format A1/B1 + return 2; + + case 12: // format A2/B2 + return 4; + + case 13: // format A3/B3 + return 6; + + default : + AssertFatal(1==0,"Invalid Prach format\n"); + break; + + } + +} + int get_nr_prach_info_from_index(uint8_t index, int frame, int slot, @@ -964,7 +1306,10 @@ int get_nr_prach_info_from_index(uint8_t index, uint16_t *format, uint8_t *start_symbol, uint8_t *N_t_slot, - uint8_t *N_dur) { + uint8_t *N_dur, + uint16_t *RA_sfn_index, + uint8_t *N_RA_slot, + uint8_t *config_period) { int x,y; int64_t s_map; @@ -980,27 +1325,39 @@ int get_nr_prach_info_from_index(uint8_t index, if ( (frame%x)==y || (frame%x)==y2 ) { slot_60khz = slot >> (mu-2); // in table slots are numbered wrt 60kHz s_map = table_6_3_3_2_4_prachConfig_Index[index][5]; + if ((s_map >> slot_60khz) & 0x01 ) { + for(int i = 0; i <= slot_60khz ;i++) { + if ( (s_map >> i) & 0x01) { + (*RA_sfn_index)++; + } + } + } if ( ((s_map>>slot_60khz)&0x01) ) { + *N_RA_slot = table_6_3_3_2_4_prachConfig_Index[index][7]; // Number of RACH slots within a subframe if (mu == 3) { - if ( (table_6_3_3_2_4_prachConfig_Index[index][7] == 1) && (slot%2 == 0) ) + if ( (*N_RA_slot == 1) && (slot%2 == 0) ) return 0; // no prach in even slots @ 120kHz for 1 prach per 60khz slot } if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *config_period = x; *start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6]; *N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8]; *N_dur = table_6_3_3_2_4_prachConfig_Index[index][9]; if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1) format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1]; *format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8); - LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame, - slot, - index, - pointa, - mu, - unpaired, - *start_symbol, - *N_t_slot, - *N_dur); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u\n", + frame, + slot, + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur, + *N_RA_slot, + *RA_sfn_index); } return 1; } @@ -1018,27 +1375,40 @@ int get_nr_prach_info_from_index(uint8_t index, if ( (frame%x)==y ) { subframe = slot >> mu; s_map = table_6_3_3_2_3_prachConfig_Index[index][4]; - if ( (s_map>>subframe)&0x01 ) { - if (mu == 1) { - if ( (table_6_3_3_2_3_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) ) - return 0; // no prach in even slots @ 30kHz for 1 prach per subframe + if ((s_map >> subframe) & 0x01 ) { + for(int i = 0; i <= subframe ;i++) { + if ( (s_map >> i) & 0x01) { + (*RA_sfn_index)++; + } } + } + if ( (s_map>>subframe)&0x01 ) { + *N_RA_slot = table_6_3_3_2_3_prachConfig_Index[index][6]; // Number of RACH slots within a subframe + if (mu == 1) { + if ( (*N_RA_slot <= 1) && (slot%2 == 0) ) + return 0; // no prach in even slots @ 30kHz for 1 prach per subframe + } if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *config_period = x; *start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5]; *N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7]; *N_dur = table_6_3_3_2_3_prachConfig_Index[index][8]; if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1) format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1]; *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8); - LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %ld) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame, - slot, - index, table_6_3_3_2_3_prachConfig_Index[index][6], - pointa, - mu, - unpaired, - *start_symbol, - *N_t_slot, - *N_dur); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d (col 6 %lu) absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u N_RA_slot %u RA_sfn_index %u \n", + frame, + slot, + index, + table_6_3_3_2_3_prachConfig_Index[index][6], + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur, + *N_RA_slot, + *RA_sfn_index); } return 1; } @@ -1066,15 +1436,16 @@ int get_nr_prach_info_from_index(uint8_t index, if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1) format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1]; *format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8); - LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame, - slot, - index, - pointa, - mu, - unpaired, - *start_symbol, - *N_t_slot, - *N_dur); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", + frame, + slot, + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur); } return 1; } @@ -1135,11 +1506,12 @@ uint16_t table_63313[838] = { uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, uint8_t nb_preambles, - uint8_t unpaired) { + uint8_t unpaired, + frequency_range_t frequency_range) { uint8_t config_index = rach_config->rach_ConfigGeneric.prach_ConfigurationIndex; uint8_t ncs_index = rach_config->rach_ConfigGeneric.zeroCorrelationZoneConfig; - uint16_t format0 = get_format0(config_index, unpaired); + uint16_t format0 = get_format0(config_index, unpaired, frequency_range); uint16_t NCS = get_NCS(ncs_index, format0, rach_config->restrictedSetConfig); uint16_t L_ra = (rach_config->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139) ? 139 : 839; uint16_t r,u,index,q,d_u,n_shift_ra,n_shift_ra_bar,d_start; @@ -1152,7 +1524,7 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, else { r = L_ra/NCS; found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r) - printf(" found_sequences %u\n", found_sequences); + LOG_D(MAC, "Computing NR root sequences: found %u sequences\n", found_sequences); return (found_sequences); } } @@ -1190,12 +1562,17 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, AssertFatal(1==0,"Procedure to find nb of sequences for restricted type B not implemented yet"); } } - printf(" found_sequences %u\n", found_sequences); + LOG_D(MAC, "Computing NR root sequences: found %u sequences\n", found_sequences); return found_sequences; } } - +// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101) +// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101) +// Notes: +// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL +// - Frequencies are expressed in KHz +// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster nr_bandentry_t nr_bandtable[] = { {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, @@ -1203,18 +1580,28 @@ nr_bandentry_t nr_bandtable[] = { {5, 824000, 849000, 869000, 894000, 20, 173800, 100}, {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100}, {8, 880000, 915000, 925000, 960000, 20, 185000, 100}, - {12, 698000, 716000, 728000, 746000, 20, 145800, 100}, + {12, 698000, 716000, 729000, 746000, 20, 145800, 100}, + {14, 788000, 798000, 758000, 768000, 20, 151600, 100}, + {18, 815000, 830000, 860000, 875000, 20, 172000, 100}, {20, 832000, 862000, 791000, 821000, 20, 158200, 100}, {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100}, + {26, 814000, 849000, 859000, 894000, 20, 171800, 100}, {28, 703000, 758000, 758000, 813000, 20, 151600, 100}, + {29, 000, 000, 717000, 728000, 20, 143400, 100}, + {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100}, {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100}, {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100}, {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100}, {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100}, {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15}, + //{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15}, + //{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30}, {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100}, {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100}, + {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100}, + {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100}, {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100}, {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100}, {71, 663000, 698000, 617000, 652000, 20, 123400, 100}, @@ -1225,22 +1612,31 @@ nr_bandentry_t nr_bandtable[] = { {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30}, {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15}, {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30}, - {79, 4400000, 5000000, 4400000, 5000000, 1, 693334, 15}, - {79, 4400000, 5000000, 4400000, 5000000, 2, 693334, 30}, + {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, + {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, {80, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {81, 860000, 915000, 000, 000, 20, 176000, 100}, + {81, 880000, 915000, 000, 000, 20, 176000, 100}, {82, 832000, 862000, 000, 000, 20, 166400, 100}, {83, 703000, 748000, 000, 000, 20, 140600, 100}, {84, 1920000, 1980000, 000, 000, 20, 384000, 100}, {86, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {257,26500000,29500000,26500000,29500000, 1,2054166, 60}, - {257,26500000,29500000,26500000,29500000, 2,2054167, 120}, - {258,24250000,27500000,24250000,27500000, 1,2016667, 60}, - {258,24250000,27500000,24250000,27500000, 2,2016667, 120}, - {260,37000000,40000000,37000000,40000000, 1,2229166, 60}, - {260,37000000,40000000,37000000,40000000, 2,2229167, 120}, - {261,27500000,28350000,27500000,28350000, 1,2070833, 60}, - {261,27500000,28350000,27500000,28350000, 2,2070833, 120} + {89, 824000, 849000, 000, 000, 20, 342000, 100}, + {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, + {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100}, + {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100}, + {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100}, + {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100}, + {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100}, + {95, 2010000, 2025000, 000, 000, 20, 402000, 100}, + {257,26500020,29500000,26500020,29500000, 1,2054166, 60}, + {257,26500080,29500000,26500080,29500000, 2,2054167, 120}, + {258,24250080,27500000,24250080,27500000, 1,2016667, 60}, + {258,24250080,27500000,24250080,27500000, 2,2016667, 120}, + {260,37000020,40000000,37000020,40000000, 1,2229166, 60}, + {260,37000080,40000000,37000080,40000000, 2,2229167, 120}, + {261,27500040,28350000,27500040,28350000, 1,2070833, 60}, + {261,27500040,28350000,27500040,28350000, 2,2070833, 120} }; @@ -1286,46 +1682,58 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = { #define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t)) -void get_band(uint64_t downlink_frequency, - uint16_t *current_band, - int32_t *current_offset, - lte_frame_type_t *current_type) -{ - int ind; - uint64_t center_frequency_khz; - uint64_t center_freq_diff_khz; - uint64_t dl_freq_khz = downlink_frequency/1000; +// Returns the corresponding row index of the NR table +int get_nr_table_idx(int nr_bandP, uint8_t scs_index){ - center_freq_diff_khz = 999999999999999999; // 2^64 - *current_band = 0; + int i, j; + int scs_khz = 15 << scs_index; + int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95}; + size_t s = sizeof(supplementary_bands)/sizeof(supplementary_bands[0]); - for ( ind=0; - ind < sizeof(nr_bandtable) / sizeof(nr_bandtable[0]); - ind++) { + for(j = 0; j < s; j++){ + if (nr_bandP == supplementary_bands[j]) + AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]); + } - 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); + AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band); + for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - if ( nr_bandtable[ind].dl_min <= dl_freq_khz && nr_bandtable[ind].dl_max >= dl_freq_khz ) { + // selection of correct Deltaf raster according to SCS + if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) + i++; - 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); + LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min); - if (*current_offset == 0) - *current_type = TDD; - else - *current_type = FDD; - } - } - } + return i; - 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); +} + +// Computes the duplex spacing (either positive or negative) in KHz +void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){ + + int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index); + + *delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min); + + LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band); + +} + +void get_frame_type(uint16_t current_band, + uint8_t scs_index, + lte_frame_type_t *current_type){ + + int32_t current_offset; + get_delta_duplex(current_band, scs_index, ¤t_offset); + + current_offset *= 1000; + if (current_offset == 0) + *current_type = TDD; + else + *current_type = FDD; + + LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset); - AssertFatal(*current_band != 0, - "Can't find EUTRA band for frequency %lu\n", downlink_frequency); } uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) @@ -1441,6 +1849,15 @@ uint16_t config_bandwidth(int mu, int nb_rb, int nr_band) } +void get_delta_arfcn(int i, uint32_t nrarfcn, uint64_t N_OFFs){ + + uint32_t delta_arfcn = nrarfcn - N_OFFs; + + if(delta_arfcn%(nr_bandtable[i].step_size)!=0) + AssertFatal(1 == 0, "nrarfcn %u is not on the channel raster for step size %lu", nrarfcn, nr_bandtable[i].step_size); + +} + uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, @@ -1448,17 +1865,10 @@ uint32_t to_nrarfcn(int nr_bandP, { uint64_t dl_CarrierFreq_by_1k = dl_CarrierFreq / 1000; int bw_kHz = bw / 1000; - int scs_khz = 15< 260\n", nr_bandP); - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - - // selection of correct Deltaf raster according to SCS - if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) - i++; AssertFatal(dl_CarrierFreq_by_1k >= nr_bandtable[i].dl_min, "Band %d, bw %u : DL carrier frequency %llu kHz < %llu\n", @@ -1470,72 +1880,90 @@ uint32_t to_nrarfcn(int nr_bandP, (long long unsigned int)(nr_bandtable[i].dl_max - bw_kHz)); int deltaFglobal = 60; + uint32_t N_REF_Offs = 2016667; + uint64_t F_REF_Offs_khz = 24250080; - if (dl_CarrierFreq < 3e9) deltaFglobal = 15; - if (dl_CarrierFreq < 24.25e9) deltaFglobal = 5; + if (dl_CarrierFreq < 24.25e9) { + deltaFglobal = 15; + N_REF_Offs = 600000; + F_REF_Offs_khz = 3000000; + } + if (dl_CarrierFreq < 3e9) { + deltaFglobal = 5; + N_REF_Offs = 0; + F_REF_Offs_khz = 0; + } // This is equation before Table 5.4.2.1-1 in 38101-1-f30 // F_REF=F_REF_Offs + deltaF_Global(N_REF-NREF_REF_Offs) - nrarfcn = (((dl_CarrierFreq_by_1k - nr_bandtable[i].dl_min)/deltaFglobal)+nr_bandtable[i].N_OFFs_DL); - - delta_arfcn = nrarfcn - nr_bandtable[i].N_OFFs_DL; - if(delta_arfcn%(nr_bandtable[i].step_size)!=0) - AssertFatal(1==0,"dl_CarrierFreq %lu corresponds to %u which is not on the raster for step size %lu", - dl_CarrierFreq,nrarfcn,nr_bandtable[i].step_size); + nrarfcn = (((dl_CarrierFreq_by_1k - F_REF_Offs_khz)/deltaFglobal)+N_REF_Offs); + get_delta_arfcn(i, nrarfcn, nr_bandtable[i].N_OFFs_DL); return nrarfcn; } - +// This function computes the RF reference frequency from the NR-ARFCN according to 5.4.2.1 of 3GPP TS 38.104 +// this function applies to both DL and UL uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, - uint32_t dl_nrarfcn) + uint32_t nrarfcn) { - int i; int deltaFglobal = 5; - int scs_khz = 15< 599999 && dl_nrarfcn < 2016667) - deltaFglobal = 15; - if (dl_nrarfcn > 2016666 && dl_nrarfcn < 3279166) + if (nrarfcn > 599999 && nrarfcn < 2016667) { + deltaFglobal = 15; + N_REF_Offs = 600000; + F_REF_Offs_khz = 3000000; + } + if (nrarfcn > 2016666 && nrarfcn < 3279166) { deltaFglobal = 60; - - AssertFatal(nr_bandP <= 261, "nr_band %d > 260\n", nr_bandP); - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - AssertFatal(dl_nrarfcn>=nr_bandtable[i].N_OFFs_DL,"dl_nrarfcn %u < N_OFFs_DL[%d] %llu\n",dl_nrarfcn, nr_bandtable[i].band,(long long unsigned int)nr_bandtable[i].N_OFFs_DL); - - // selection of correct Deltaf raster according to SCS - if ( (nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz)) - i++; + N_REF_Offs = 2016667; + F_REF_Offs_khz = 24250080; + } - delta_arfcn = dl_nrarfcn - nr_bandtable[i].N_OFFs_DL; - if(delta_arfcn%(nr_bandtable[i].step_size)!=0) - AssertFatal(1==0,"dl_nrarfcn %u is not on the raster for step size %lu",dl_nrarfcn,nr_bandtable[i].step_size); + get_delta_duplex(nr_bandP, scs_index, &delta_duplex); - 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); + if (delta_duplex <= 0){ // DL band >= UL band + if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL + N_OFFs = nr_bandtable[i].N_OFFs_DL; + freq_min = nr_bandtable[i].dl_min; + } else {// is FDD UL + N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; + freq_min = nr_bandtable[i].ul_min; + } + } else { // UL band > DL band + if (nrarfcn >= nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal){ // is FDD UL + N_OFFs = nr_bandtable[i].N_OFFs_DL + delta_duplex/deltaFglobal; + freq_min = nr_bandtable[i].ul_min; + } else { // is FDD DL + N_OFFs = nr_bandtable[i].N_OFFs_DL; + freq_min = nr_bandtable[i].dl_min; + } + } + + LOG_D(MAC, "Frequency from NR-ARFCN for N_OFFs %lu, duplex spacing %d KHz, deltaFglobal %d KHz\n", N_OFFs, delta_duplex, deltaFglobal); + + AssertFatal(nrarfcn >= N_OFFs,"nrarfcn %u < N_OFFs[%d] %llu\n", nrarfcn, nr_bandtable[i].band, (long long unsigned int)N_OFFs); + get_delta_arfcn(i, nrarfcn, N_OFFs); + + frequency = 1000*(F_REF_Offs_khz + (nrarfcn - N_REF_Offs) * deltaFglobal); + + LOG_I(MAC, "Computing frequency (pointA %llu => %llu KHz (freq_min %llu KHz, NR band %d N_OFFs %llu))\n", + (unsigned long long)nrarfcn, + (unsigned long long)frequency/1000, + (unsigned long long)freq_min, + nr_bandP, + (unsigned long long)N_OFFs); + + return frequency; - return 1000*(nr_bandtable[i].dl_min + (dl_nrarfcn - nr_bandtable[i].N_OFFs_DL) * deltaFglobal); } - -int32_t get_nr_uldl_offset(int nr_bandP) -{ - int i; - - for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++); - - AssertFatal(i < NR_BANDTABLE_SIZE, "i %d >= BANDTABLE_SIZE %ld\n", i, NR_BANDTABLE_SIZE); - - 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, uint8_t numdmrscdmgroupnodata, @@ -1556,7 +1984,8 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, } 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; + uint16_t dmrs_length = get_num_dmrs(pdsch_rel15->dlDmrsSymbPos); + uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS*dmrs_length - 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; @@ -1573,10 +2002,10 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, TBS = nr_compute_tbs(Qm, R, - pdsch_rel15->rbSize, - N_sh_symb, - N_PRB_DMRS, // FIXME // This should be multiplied by the number of dmrs symbols - N_PRB_oh, + pdsch_rel15->rbSize, + N_sh_symb, + N_PRB_DMRS*dmrs_length, + N_PRB_oh, tb_scaling, pdsch_rel15->nrOfLayers)>>3; @@ -1616,7 +2045,7 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][0]); break; @@ -1624,7 +2053,7 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][0]); break; @@ -1632,13 +2061,14 @@ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][0]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + return 0; } } @@ -1647,7 +2077,7 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][1]); break; @@ -1655,7 +2085,7 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][1]); break; @@ -1663,13 +2093,14 @@ uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][1]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); + return 0; } } @@ -1678,7 +2109,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][0]); break; @@ -1686,7 +2117,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][0]); break; @@ -1694,7 +2125,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][0]); break; @@ -1702,7 +2133,7 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 3: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61411[Imcs][0]); break; @@ -1710,13 +2141,14 @@ uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { case 4: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61412[Imcs][0]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + return 0; } } @@ -1725,7 +2157,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 0: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51311[Imcs][1]); break; @@ -1733,7 +2165,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 1: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_51312[Imcs][1]); break; @@ -1741,7 +2173,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 2: if (Imcs > 28) { LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); - Imcs = 28; + return 0; } return (Table_51313[Imcs][1]); break; @@ -1749,7 +2181,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 3: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61411[Imcs][1]); break; @@ -1757,13 +2189,14 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { case 4: if (Imcs > 27) { LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs); - Imcs = 27; + return 0; } return (Table_61412[Imcs][1]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + LOG_E(MAC, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); + return 0; } } @@ -1794,6 +2227,10 @@ int get_num_dmrs(uint16_t dmrs_mask ) { for (int i=0;i<16;i++) num_dmrs+=((dmrs_mask>>i)&1); return(num_dmrs); } +/* returns the total DMRS symbols in a slot*/ +uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols){ + return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols)); +} // Table 5.1.2.2.1-1 38.214 uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) { @@ -1943,8 +2380,44 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) { return 4; } -uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *secondaryCellGroup, +// Set the transform precoding status according to 6.1.3 of 3GPP TS 38.214 version 16.3.0 Release 16: +// - "UE procedure for applying transform precoding on PUSCH" +uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc, + const NR_PUSCH_Config_t *pusch_config, + const NR_BWP_Uplink_t *ubwp, + uint8_t *dci_format, + int rnti_type, + uint8_t configuredGrant){ + + if (configuredGrant) { + if (ubwp->bwp_Dedicated->configuredGrantConfig) { + if (ubwp->bwp_Dedicated->configuredGrantConfig->choice.setup->transformPrecoder) { + return *ubwp->bwp_Dedicated->configuredGrantConfig->choice.setup->transformPrecoder; + } + } + } + + if (rnti_type != NR_RNTI_RA) { + if (*dci_format != NR_UL_DCI_FORMAT_0_0) { + if (pusch_config->transformPrecoder != NULL) { + return *pusch_config->transformPrecoder; + } + } + } + + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) { + return 1; // Transformprecoding disabled + } else { + LOG_D(PHY, "MAC_COMMON: Transform Precodig enabled through msg3_transformPrecoder\n"); + return 0; // Enabled + } + + LOG_E(MAC, "In %s: could not fetch transform precoder status...\n", __FUNCTION__); + return -1; +} + +uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu, nr_dci_format_t format, nr_rnti_type_t rnti_type, @@ -1956,11 +2429,19 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, long rbg_size_config; int num_entries = 0; int pusch_antenna_ports = 1; // TODO hardcoded number of antenna ports for pusch - NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; - NR_PDSCH_Config_t *pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup; - NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup; - NR_SRS_Config_t *srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup; + + NR_BWP_Downlink_t *bwp = NULL; + NR_BWP_Uplink_t *ubwp = NULL; + NR_PDSCH_Config_t *pdsch_config = NULL; + NR_PUSCH_Config_t *pusch_Config = NULL; + NR_SRS_Config_t *srs_config = NULL; + if(bwp_id > 0) { + bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; + pdsch_config = bwp->bwp_Dedicated->pdsch_Config->choice.setup; + pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup; + srs_config = ubwp->bwp_Dedicated->srs_Config->choice.setup; + } switch(format) { /*Only sizes for 0_0 and 1_0 are correct at the moment*/ @@ -1997,8 +2478,8 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, rbg_size_config = 1; else rbg_size_config = 0; - numRBG = getNRBG(NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275), - NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275), + numRBG = getNRBG(NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE), + NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE), rbg_size_config); if (pusch_Config->resourceAllocation == 0) dci_pdu->frequency_domain_assignment.nbits = numRBG; @@ -2072,16 +2553,8 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, } } // Precoding info and number of layers - long transformPrecoder; - if (pusch_Config->transformPrecoder == NULL){ - // if transform precoder is null, apply the values from msg3 - if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - transformPrecoder = 1; - else - transformPrecoder = 0; - } - else - transformPrecoder = *pusch_Config->transformPrecoder; + long transformPrecoder = get_transformPrecoding(scc, pusch_Config, ubwp, (uint8_t*)&format, rnti_type, 0); + if (pusch_Config->txConfig != NULL){ if (*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook){ if (pusch_antenna_ports > 1) { @@ -2165,8 +2638,13 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, 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 = 28; size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment + + dci_pdu->frequency_domain_assignment.nbits = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + dci_pdu->time_domain_assignment.nbits = 4; + dci_pdu->vrb_to_prb_mapping.nbits = 1; + break; case NR_DL_DCI_FORMAT_1_1: @@ -2187,8 +2665,8 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, size += dci_pdu->bwp_indicator.nbits; // Freq domain assignment rbg_size_config = secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size; - numRBG = getNRBG(NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), - NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), + numRBG = getNRBG(NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE), + NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE), rbg_size_config); if (pdsch_config->resourceAllocation == 0) dci_pdu->frequency_domain_assignment.nbits = numRBG; @@ -2416,8 +2894,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i case 5 : case 6 : case 7 : - AssertFatal(1==0,"Incoompatible NrOfSymbols %d and dmrs_Additional_Position %d\n", - NrOfSymbols,(int)*dmrs_config->dmrs_AdditionalPosition); + return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) + if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) + if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3) + else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) + if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3) + else if (dmrs_config->dmrs_AdditionalPosition && *dmrs_config->dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos3) 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_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_DownlinkForPDSCH_MappingTypeB && @@ -2519,3 +2998,442 @@ int binomial(int n, int k) { return c; } +/* extract PTRS values from RC and validate it based upon 38.214 5.1.6.3 */ +bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, + uint16_t rbSize,uint8_t mcsIndex, uint8_t mcsTable, + uint8_t *K_ptrs, uint8_t *L_ptrs, + uint8_t *portIndex,uint8_t *nERatio, uint8_t *reOffset, + uint8_t NrOfSymbols) +{ + bool valid = true; + + /* as defined in T 38.214 5.1.6.3 */ + if(rbSize < 3) { + valid = false; + return valid; + } + /* Check for Frequency Density values */ + if(ptrs_config->frequencyDensity->list.count < 2) { + /* Default value for K_PTRS = 2 as defined in T 38.214 5.1.6.3 */ + *K_ptrs = 2; + } + else { + *K_ptrs = get_K_ptrs(*ptrs_config->frequencyDensity->list.array[0], + *ptrs_config->frequencyDensity->list.array[1], + rbSize); + } + /* Check for time Density values */ + if(ptrs_config->timeDensity->list.count < 3) { + /* Default value for L_PTRS = 1 as defined in T 38.214 5.1.6.3 */ + *L_ptrs = 1; + } + else { + *L_ptrs = get_L_ptrs(*ptrs_config->timeDensity->list.array[0], + *ptrs_config->timeDensity->list.array[1], + *ptrs_config->timeDensity->list.array[2], + mcsIndex, + mcsTable); + } + *portIndex =*ptrs_config->epre_Ratio; + *nERatio = *ptrs_config->resourceElementOffset; + *reOffset = 0; + /* If either or both of the parameters PT-RS time density (LPT-RS) and PT-RS frequency density (KPT-RS), shown in Table + * 5.1.6.3-1 and Table 5.1.6.3-2, indicates that 'PT-RS not present', the UE shall assume that PT-RS is not present + */ + if(*K_ptrs ==2 || *K_ptrs ==4 ) { + valid = true; + } + else { + valid = false; + return valid; + } + if(*L_ptrs ==0 || *L_ptrs ==1 || *L_ptrs ==2 ) { + valid = true; + } + else { + valid = false; + return valid; + } + /* PTRS is not present also : + * When the UE is receiving a PDSCH with allocation duration of 4 symbols and if LPT-RS is set to 4, the UE shall assume + * PT-RS is not transmitted + * When the UE is receiving a PDSCH with allocation duration of 2 symbols as defined in Clause 7.4.1.1.2 of [4, TS + * 38.211] and if LPT-RS is set to 2 or 4, the UE shall assume PT-RS is not transmitted. + */ + if((NrOfSymbols == 4 && *L_ptrs ==2) || ((NrOfSymbols == 2 && *L_ptrs > 0))) { + valid = false; + return valid; + } + //printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs); + return valid; +} +uint32_t get_ssb_slot(uint32_t ssb_index){ + // this function now only support f <= 3GHz + return ssb_index & 0x3 ; + + // return first_symbol(case, freq, ssb_index) / 14 +} + +int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + NR_MIB_t *mib, + uint8_t extra_bits, + uint32_t ssb_length, + uint32_t ssb_index, + uint32_t ssb_offset_point_a) { + + // deafult for testing + subcarrier_spacing_t scs_ssb = scs_30kHz; + channel_bandwidth_t min_channel_bw = bw_10MHz; + frequency_range_t frequency_range = FR1; + const uint32_t num_slot_per_frame = 20; + + type0_PDCCH_CSS_config->ssb_length = ssb_length; + type0_PDCCH_CSS_config->ssb_index = ssb_index; + type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused); + + uint16_t frame_number_4lsb = 0; + for (int i=0; i<4; i++) { + frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i); + } + + uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5] + uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset; + + type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4; + type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb; + + if(type0_PDCCH_CSS_config->ssb_length == 64){ + type0_PDCCH_CSS_config->ssb_index = type0_PDCCH_CSS_config->ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] } + }else{ + if(ssb_subcarrier_offset_msb){ + ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10; + } + } + + // assume carrier frequency < 6GHz + subcarrier_spacing_t scs_pdcch; + if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){ + scs_pdcch = scs_15kHz; + }else{ //NR_MIB__subCarrierSpacingCommon_scs30or120 + scs_pdcch = scs_30kHz; + } + + uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13 + uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero); + uint32_t index_4lsb = (mib->pdcch_ConfigSIB1.searchSpaceZero); + + type0_PDCCH_CSS_config->num_rbs = -1; + type0_PDCCH_CSS_config->num_symbols = -1; + type0_PDCCH_CSS_config->rb_offset = -1; + + // type0-pdcch coreset + switch( (scs_ssb << 5) | scs_pdcch ){ + case (scs_15kHz << 5) | scs_15kHz : + AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n"); + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_1_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb]; + break; + + case (scs_15kHz << 5) | scs_30kHz: + AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n"); + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_2_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb]; + break; + + case (scs_30kHz << 5) | scs_15kHz: + if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ + AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n"); + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_3_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_3_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_3_c4[index_4msb]; + }else if(min_channel_bw & bw_40MHz){ + AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n"); + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_5_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_5_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_5_c4[index_4msb]; + }else{ ; } + + break; + + case (scs_30kHz << 5) | scs_30kHz: + if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_4_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_4_c4[index_4msb]; + + }else if(min_channel_bw & bw_40MHz){ + AssertFatal(index_4msb < 10, "38.213 Table 13-6 4 MSB out of range\n"); + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_6_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_6_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_6_c4[index_4msb]; + }else{ ; } + break; + + case (scs_120kHz << 5) | scs_60kHz: + AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n"); + if(index_4msb & 0x7){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + }else if(index_4msb & 0x18){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 2; + }else{ ; } + + type0_PDCCH_CSS_config->num_rbs = table_38213_13_7_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_7_c3[index_4msb]; + if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){ + type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb] - 1; + }else{ + type0_PDCCH_CSS_config->rb_offset = table_38213_13_7_c4[index_4msb]; + } + break; + + case (scs_120kHz << 5) | scs_120kHz: + AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n"); + if(index_4msb & 0x3){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + }else if(index_4msb & 0x0c){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 3; + } + + type0_PDCCH_CSS_config->num_rbs = table_38213_13_8_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_8_c3[index_4msb]; + if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){ + type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb] - 1; + }else{ + type0_PDCCH_CSS_config->rb_offset = table_38213_13_8_c4[index_4msb]; + } + break; + + case (scs_240kHz << 5) | scs_60kHz: + AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n"); + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_9_c3[index_4msb]; + type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb]; + break; + + case (scs_240kHz << 5) | scs_120kHz: + AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n"); + if(index_4msb & 0x3){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1; + }else if(index_4msb & 0x0c){ + type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 2; + } + type0_PDCCH_CSS_config->num_rbs = table_38213_13_10_c2[index_4msb]; + type0_PDCCH_CSS_config->num_symbols = table_38213_13_10_c3[index_4msb]; + if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){ + type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb]-1; + }else{ + type0_PDCCH_CSS_config->rb_offset = table_38213_13_10_c4[index_4msb]; + } + + break; + + default: + break; + } + + LOG_D(MAC,"Coreset0: index_4msb=%d, num_rbs=%d, num_symb=%d, rb_offset=%d\n", + index_4msb,type0_PDCCH_CSS_config->num_rbs,type0_PDCCH_CSS_config->num_symbols,type0_PDCCH_CSS_config->rb_offset ); + + AssertFatal(type0_PDCCH_CSS_config->num_rbs != -1, "Type0 PDCCH coreset num_rbs undefined"); + AssertFatal(type0_PDCCH_CSS_config->num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined"); + AssertFatal(type0_PDCCH_CSS_config->rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined"); + + + //uint32_t cell_id = 0; // obtain from L1 later + + //mac->type0_pdcch_dci_config.coreset.rb_start = rb_offset; + //mac->type0_pdcch_dci_config.coreset.rb_end = rb_offset + num_rbs - 1; + +// uint64_t mask = 0x0; +// uint8_t i; +// for(i=0; i<(type0_PDCCH_CSS_config->num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs +// mask = mask >> 1; +// 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; + + + // type0-pdcch search space + float big_o = 0.0f; + float big_m = 0.0f; + type0_PDCCH_CSS_config->sfn_c = SFN_C_IMPOSSIBLE; // only valid for mux=1 + type0_PDCCH_CSS_config->n_c = UINT_MAX; + type0_PDCCH_CSS_config->number_of_search_space_per_slot = UINT_MAX; + type0_PDCCH_CSS_config->first_symbol_index = UINT_MAX; + type0_PDCCH_CSS_config->search_space_duration = 0; // element of search space + // 38.213 table 10.1-1 + + /// MUX PATTERN 1 + if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){ + big_o = table_38213_13_11_c1[index_4lsb]; + type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; + big_m = table_38213_13_11_c3[index_4lsb]; + + uint32_t temp = (uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m); + type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame; + if((temp/num_slot_per_frame) & 0x1){ + type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1; + }else{ + type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_0; + } + + if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (type0_PDCCH_CSS_config->ssb_index&1)){ + type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols; + }else{ + type0_PDCCH_CSS_config->first_symbol_index = table_38213_13_11_c4[index_4lsb]; + } + // 38.213 chapter 13: over two consecutive slots + type0_PDCCH_CSS_config->search_space_duration = 2; + } + + if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){ + big_o = table_38213_13_12_c1[index_4lsb]; + type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; + big_m = table_38213_13_12_c3[index_4lsb]; + + if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (type0_PDCCH_CSS_config->ssb_index&1)){ + type0_PDCCH_CSS_config->first_symbol_index = 7; + }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (type0_PDCCH_CSS_config->ssb_index&1)){ + type0_PDCCH_CSS_config->first_symbol_index = type0_PDCCH_CSS_config->num_symbols; + }else{ + type0_PDCCH_CSS_config->first_symbol_index = 0; + } + // 38.213 chapter 13: over two consecutive slots + type0_PDCCH_CSS_config->search_space_duration = 2; + } + + /// MUX PATTERN 2 + if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){ + + if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){ + // 38.213 Table 13-13 + AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n"); + // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot + // sfn_c = SFN_C_EQ_SFN_SSB; + type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index); + switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4 + case 0: + type0_PDCCH_CSS_config->first_symbol_index = 0; + break; + case 1: + type0_PDCCH_CSS_config->first_symbol_index = 1; + break; + case 2: + type0_PDCCH_CSS_config->first_symbol_index = 6; + break; + case 3: + type0_PDCCH_CSS_config->first_symbol_index = 7; + break; + default: break; + } + + }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ + // 38.213 Table 13-14 + AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n"); + // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot + // sfn_c = SFN_C_EQ_SFN_SSB; + type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index); + switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8 + case 0: + type0_PDCCH_CSS_config->first_symbol_index = 0; + break; + case 1: + type0_PDCCH_CSS_config->first_symbol_index = 1; + break; + case 2: + type0_PDCCH_CSS_config->first_symbol_index = 2; + break; + case 3: + type0_PDCCH_CSS_config->first_symbol_index = 3; + break; + case 4: + type0_PDCCH_CSS_config->first_symbol_index = 12; + type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1; + break; + case 5: + type0_PDCCH_CSS_config->first_symbol_index = 13; + type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1; + break; + case 6: + type0_PDCCH_CSS_config->first_symbol_index = 0; + break; + case 7: + type0_PDCCH_CSS_config->first_symbol_index = 1; + break; + default: break; + } + }else{ ; } + // 38.213 chapter 13: over one slot + type0_PDCCH_CSS_config->search_space_duration = 1; + } + + /// MUX PATTERN 3 + if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){ + if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){ + // 38.213 Table 13-15 + AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n"); + // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot + // sfn_c = SFN_C_EQ_SFN_SSB; + type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index); + switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4 + case 0: + type0_PDCCH_CSS_config->first_symbol_index = 4; + break; + case 1: + type0_PDCCH_CSS_config->first_symbol_index = 8; + break; + case 2: + type0_PDCCH_CSS_config->first_symbol_index = 2; + break; + case 3: + type0_PDCCH_CSS_config->first_symbol_index = 6; + break; + default: break; + } + }else{ ; } + // 38.213 chapter 13: over one slot + type0_PDCCH_CSS_config->search_space_duration = 1; + } + + AssertFatal(type0_PDCCH_CSS_config->number_of_search_space_per_slot!=UINT_MAX,""); + +// uint32_t 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 +// 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(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,""); + AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,""); + + type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame; + type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset; + + return 0; +} diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index f19a46cb34..58ecd54733 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -20,53 +20,28 @@ */ /*! \file mac.h -* \brief MAC data structures, constant, and function prototype +* \brief common MAC function prototypes * \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__ +#include "NR_MIB.h" #include "NR_PDSCH-Config.h" #include "NR_CellGroupConfig.h" #include "nr_mac.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_MCS_C, -} nr_rnti_type_t; +#include "openair1/PHY/impl_defs_nr.h" uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); -void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); +void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type); + +void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex); uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); @@ -78,14 +53,18 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); -uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *secondaryCellGroup, +uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu, nr_dci_format_t format, nr_rnti_type_t rnti_type, uint16_t N_RB, int bwp_id); +void find_aggregation_candidates(uint8_t *aggregation_level, + uint8_t *nr_of_candidates, + NR_SearchSpace_t *ss); + void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, uint16_t *slot_period, uint16_t *offset); @@ -99,7 +78,24 @@ int get_nr_prach_info_from_index(uint8_t index, uint16_t *format, uint8_t *start_symbol, uint8_t *N_t_slot, - uint8_t *N_dur); + uint8_t *N_dur, + uint16_t *RA_sfn_index, + uint8_t *N_RA_slot, + uint8_t *config_period); + +int get_nr_prach_occasion_info_from_index(uint8_t index, + uint32_t pointa, + uint8_t mu, + uint8_t unpaired, + uint16_t *format, + uint8_t *start_symbol, + uint8_t *N_t_slot, + uint8_t *N_dur, + uint8_t *N_RA_slot, + uint16_t *N_RA_sfn, + uint8_t *max_association_period); + +uint8_t get_nr_prach_duration(uint8_t prach_format); uint8_t get_pusch_mcs_table(long *mcs_Table, int is_tp, @@ -110,11 +106,16 @@ uint8_t get_pusch_mcs_table(long *mcs_Table, uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, uint8_t nb_preambles, - uint8_t unpaired); + uint8_t unpaired, + frequency_range_t); int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder); -int get_format0(uint8_t index, uint8_t unpaired); +int get_format0(uint8_t index, uint8_t unpaired,frequency_range_t); + +int64_t *get_prach_config_info(uint32_t pointa, + uint8_t index, + uint8_t unpaired); uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config); @@ -125,4 +126,35 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table); uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB); +int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, + NR_MIB_t *mib, + uint8_t extra_bits, + uint32_t ssb_length, + uint32_t ssb_index, + uint32_t ssb_offset_point_a); + +int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH); + +bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config, + uint16_t rbSize, uint8_t mcsIndex, uint8_t mcsTable, + uint8_t *K_ptrs, uint8_t *L_ptrs,uint8_t *portIndex, + uint8_t *nERatio,uint8_t *reOffset, + uint8_t NrOfSymbols); + +uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols); + +/* \brief Set the transform precoding according to 6.1.3 of 3GPP TS 38.214 version 16.3.0 Release 16 +@param *pusch_config, pointer to pusch config +@param *ubwp pointer to uplink bwp +@param *dci_format pointer to dci format +@param rnti_type rnti type +@param configuredGrant indicates whether a configured grant was received or not +@returns transformPrecoding value */ +uint8_t get_transformPrecoding(const NR_ServingCellConfigCommon_t *scc, + const NR_PUSCH_Config_t *pusch_config, + const NR_BWP_Uplink_t *ubwp, + uint8_t *dci_format, + int rnti_type, + uint8_t configuredGrant); + #endif diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 5c714e4a93..8f7a726bb8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -37,6 +37,8 @@ /*#include "PHY/defs_common.h"*/ +extern const uint8_t nr_slots_per_frame[5]; + /* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE]; extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; @@ -75,5 +77,66 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif*/ +// Type0-PDCCH search space +extern const int32_t table_38213_13_1_c1[16]; +extern const int32_t table_38213_13_1_c2[16]; +extern const int32_t table_38213_13_1_c3[16]; +extern const int32_t table_38213_13_1_c4[16]; + +extern const int32_t table_38213_13_2_c1[16]; +extern const int32_t table_38213_13_2_c2[16]; +extern const int32_t table_38213_13_2_c3[16]; +extern const int32_t table_38213_13_2_c4[16]; + +extern const int32_t table_38213_13_3_c1[16]; +extern const int32_t table_38213_13_3_c2[16]; +extern const int32_t table_38213_13_3_c3[16]; +extern const int32_t table_38213_13_3_c4[16]; + +extern const int32_t table_38213_13_4_c1[16]; +extern const int32_t table_38213_13_4_c2[16]; +extern const int32_t table_38213_13_4_c3[16]; +extern const int32_t table_38213_13_4_c4[16]; + +extern const int32_t table_38213_13_5_c1[16]; +extern const int32_t table_38213_13_5_c2[16]; +extern const int32_t table_38213_13_5_c3[16]; +extern const int32_t table_38213_13_5_c4[16]; + +extern const int32_t table_38213_13_6_c1[16]; +extern const int32_t table_38213_13_6_c2[16]; +extern const int32_t table_38213_13_6_c3[16]; +extern const int32_t table_38213_13_6_c4[16]; + +extern const int32_t table_38213_13_7_c1[16]; +extern const int32_t table_38213_13_7_c2[16]; +extern const int32_t table_38213_13_7_c3[16]; +extern const int32_t table_38213_13_7_c4[16]; + +extern const int32_t table_38213_13_8_c1[16]; +extern const int32_t table_38213_13_8_c2[16]; +extern const int32_t table_38213_13_8_c3[16]; +extern const int32_t table_38213_13_8_c4[16]; + +extern const int32_t table_38213_13_9_c1[16]; +extern const int32_t table_38213_13_9_c2[16]; +extern const int32_t table_38213_13_9_c3[16]; +extern const int32_t table_38213_13_9_c4[16]; + +extern const int32_t table_38213_13_10_c1[16]; +extern const int32_t table_38213_13_10_c2[16]; +extern const int32_t table_38213_13_10_c3[16]; +extern const int32_t table_38213_13_10_c4[16]; + +extern const float table_38213_13_11_c1[16]; +extern const int32_t table_38213_13_11_c2[16]; +extern const float table_38213_13_11_c3[16]; +extern const int32_t table_38213_13_11_c4[16]; + +extern const float table_38213_13_12_c1[16]; +extern const int32_t table_38213_13_12_c2[16]; +extern const float table_38213_13_12_c3[16]; + +extern const int32_t table_38213_10_1_1_c2[5]; #endif //DEF_H diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index bc98e16d39..f6bd5436bc 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -82,6 +82,7 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, } int nb_slots_per_period = ((1<tdd_table.tdd_period_in_slots = nb_slots_per_period; if ( (nrofDownlinkSymbols + nrofUplinkSymbols) == 0 ) AssertFatal(nb_slots_per_period == (nrofDownlinkSlots + nrofUplinkSlots), @@ -152,8 +153,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, mac->phy_config.CC_id = cc_idP; // carrier config - - LOG_I(MAC,"UE Config Common\n"); + LOG_D(MAC, "Entering UE Config Common\n"); cfg->carrier_config.dl_bandwidth = config_bandwidth(scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth, @@ -200,15 +200,11 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } } + uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + frequency_range_t frequency_range = band<100?FR1:FR2; + lte_frame_type_t frame_type; - uint16_t band; - int32_t offset; - - get_band((cfg->carrier_config.dl_frequency)*1000, - &band, - &offset, - &frame_type); - + get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); // cell config @@ -243,8 +239,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; for (i=0; i<4; i++) { - cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530 is null\n"); cfg->tdd_table.tdd_period = *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); if(cfg->cell_config.frame_duplex_type == TDD){ + LOG_I(MAC,"Setting TDD configuration period to %d\n", cfg->tdd_table.tdd_period); int return_tdd = set_tdd_config_nr_ue(cfg, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots, @@ -317,7 +313,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart; cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; - cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type); + cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type,frequency_range); //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ??? } @@ -325,6 +321,47 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } +/** \brief This function performs some configuration routines according to clause 12 "Bandwidth part operation" 3GPP TS 38.213 version 16.3.0 Release 16 + @param NR_UE_MAC_INST_t mac: pointer to local MAC instance + @returns void + */ +void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format){ + + NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; + + if (bwp_ind && dci_format){ + + switch(*dci_format){ + case NR_UL_DCI_FORMAT_0_1: + mac->UL_BWP_Id = *bwp_ind; + break; + case NR_DL_DCI_FORMAT_1_1: + mac->DL_BWP_Id = *bwp_ind; + break; + default: + LOG_E(MAC, "In %s: failed to configure BWP Id from DCI with format %d \n", __FUNCTION__, *dci_format); + } + + } else { + + if (scd->firstActiveDownlinkBWP_Id) + mac->DL_BWP_Id = *scd->firstActiveDownlinkBWP_Id; + else if (scd->defaultDownlinkBWP_Id) + mac->DL_BWP_Id = *scd->defaultDownlinkBWP_Id; + else + mac->DL_BWP_Id = 1; + + if (scd->uplinkConfig && scd->uplinkConfig->firstActiveUplinkBWP_Id) + mac->UL_BWP_Id = *scd->uplinkConfig->firstActiveUplinkBWP_Id; + else + mac->UL_BWP_Id = 1; + + } + + LOG_D(MAC, "In %s setting DL_BWP_Id %ld UL_BWP_Id %ld \n", __FUNCTION__, mac->DL_BWP_Id, mac->UL_BWP_Id); + +} + /** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and \brief performs assert checks on the relevant RRC configuration. @param NR_UE_MAC_INST_t mac: pointer to local MAC instance @@ -332,15 +369,20 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, */ void config_control_ue(NR_UE_MAC_INST_t *mac){ - uint8_t bwp_id = 1, coreset_id = 1, ss_id; + uint8_t coreset_id = 1, ss_id; + NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n"); AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count); - NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Common; + config_bwp_ue(mac, NULL, NULL); + NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id; + AssertFatal(dl_bwp_id != 0, "DL_BWP_Id is 0!"); + + NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[dl_bwp_id - 1]->bwp_Common; AssertFatal(bwp_Common != NULL, "bwp_Common is null\n"); - NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Dedicated; + NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[dl_bwp_id - 1]->bwp_Dedicated; AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n"); NR_SetupRelease_PDCCH_Config_t *pdcch_Config = dl_bwp_Dedicated->pdcch_Config; @@ -369,8 +411,8 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){ AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count); // check pdcch_Config, pdcch_ConfigCommon and DL BWP - mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; - mac->coreset[bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0]; + mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[dl_bwp_id - 1]; + mac->coreset[dl_bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0]; // Check dedicated UL BWP and pass to MAC mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[0]; @@ -382,7 +424,7 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){ NR_SearchSpace_t *ss = searchSpacesToAddModList->list.array[ss_id]; AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); - AssertFatal(*ss->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); + AssertFatal(*ss->controlResourceSetId == mac->coreset[dl_bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); AssertFatal(ss->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n"); AssertFatal(ss->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n"); mac->SSpace[0][0][ss_id] = ss; @@ -393,14 +435,74 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){ for (int css_id = 0; css_id < commonSearchSpaceList->list.count; css_id++) { NR_SearchSpace_t *css = commonSearchSpaceList->list.array[css_id]; AssertFatal(css->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); - AssertFatal(*css->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); - AssertFatal(css->searchSpaceId != 0, "css->searchSpaceId is 0\n"); + AssertFatal(*css->controlResourceSetId == mac->coreset[dl_bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); AssertFatal(css->searchSpaceType != NULL, "css->searchSpaceType is null\n"); AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n"); AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n"); mac->SSpace[0][0][ss_id] = css; ss_id++; } + + // TODO: Merge this code in a single function as fill_default_searchSpaceZero() in rrc_gNB_reconfig.c + // Search space zero + if(mac->search_space_zero == NULL) mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); + if(mac->search_space_zero->controlResourceSetId == NULL) mac->search_space_zero->controlResourceSetId=calloc(1,sizeof(*mac->search_space_zero->controlResourceSetId)); + if(mac->search_space_zero->monitoringSymbolsWithinSlot == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot = calloc(1,sizeof(*mac->search_space_zero->monitoringSymbolsWithinSlot)); + if(mac->search_space_zero->monitoringSymbolsWithinSlot->buf == NULL) mac->search_space_zero->monitoringSymbolsWithinSlot->buf = calloc(1,2); + if(mac->search_space_zero->nrofCandidates == NULL) mac->search_space_zero->nrofCandidates = calloc(1,sizeof(*mac->search_space_zero->nrofCandidates)); + if(mac->search_space_zero->searchSpaceType == NULL) mac->search_space_zero->searchSpaceType = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType)); + if(mac->search_space_zero->searchSpaceType->choice.common == NULL) mac->search_space_zero->searchSpaceType->choice.common=calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common)); + if(mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*mac->search_space_zero->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); + mac->search_space_zero->searchSpaceId = 0; + *mac->search_space_zero->controlResourceSetId = 0; + mac->search_space_zero->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*mac->search_space_zero->monitoringSlotPeriodicityAndOffset)); + mac->search_space_zero->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; + mac->search_space_zero->duration=NULL; + // should be '1100 0000 0000 00'B (LSB first!), first two symbols in slot, adjust if needed + mac->search_space_zero->monitoringSymbolsWithinSlot->buf[1] = 0; + mac->search_space_zero->monitoringSymbolsWithinSlot->buf[0] = (1<<7); + mac->search_space_zero->monitoringSymbolsWithinSlot->size = 2; + mac->search_space_zero->monitoringSymbolsWithinSlot->bits_unused = 2; + + // FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1 + mac->search_space_zero->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + mac->search_space_zero->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + mac->search_space_zero->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2; + mac->search_space_zero->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; + mac->search_space_zero->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + mac->search_space_zero->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; + + // Coreset0 + if(mac->coreset0 == NULL) mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); + mac->coreset0->controlResourceSetId = 0; + // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B, + if(mac->coreset0->frequencyDomainResources.buf == NULL) mac->coreset0->frequencyDomainResources.buf = calloc(1,6); + mac->coreset0->frequencyDomainResources.buf[0] = 0xff; + mac->coreset0->frequencyDomainResources.buf[1] = 0; + mac->coreset0->frequencyDomainResources.buf[2] = 0; + mac->coreset0->frequencyDomainResources.buf[3] = 0; + mac->coreset0->frequencyDomainResources.buf[4] = 0; + mac->coreset0->frequencyDomainResources.buf[5] = 0; + mac->coreset0->frequencyDomainResources.size = 6; + mac->coreset0->frequencyDomainResources.bits_unused = 3; + mac->coreset0->duration = 1; + mac->coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; + mac->coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*mac->coreset0->cce_REG_MappingType.choice.interleaved)); + mac->coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6; + mac->coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2; + mac->coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = NULL; + mac->coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; + if(mac->coreset0->tci_StatesPDCCH_ToAddList == NULL) mac->coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*mac->coreset0->tci_StatesPDCCH_ToAddList)); + NR_TCI_StateId_t *tci[8]; + for (int i=0;i<8;i++) { + tci[i]=calloc(1,sizeof(*tci[i])); + *tci[i] = i; + ASN_SEQUENCE_ADD(&mac->coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]); + } + mac->coreset0->tci_StatesPDCCH_ToReleaseList = NULL; + mac->coreset0->tci_PresentInDCI = NULL; + mac->coreset0->pdcch_DMRS_ScramblingID = NULL; + } int nr_rrc_mac_config_req_ue( @@ -414,6 +516,7 @@ int nr_rrc_mac_config_req_ue( NR_CellGroupConfig_t *cell_group_config ){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + RA_config_t *ra = &mac->ra; // TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc. @@ -426,13 +529,16 @@ int nr_rrc_mac_config_req_ue( mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex; config_control_ue(mac); if (cell_group_config->spCellConfig->reconfigurationWithSync) { - mac->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; config_common_ue(mac,module_id,cc_idP); mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); } + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); + /* if(mac_cell_group_configP != NULL){ if(mac_cell_group_configP->drx_Config != NULL ){ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index fdee0e76d4..dd0aa15c52 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -20,7 +20,7 @@ */ /* \file mac_defs.h - * \brief MAC data structures, constant, and function prototype + * \brief MAC data structures and constants * \author R. Knopp, K.H. HSU * \date 2018 * \version 0.1 @@ -69,19 +69,106 @@ #include "PHY/defs_nr_common.h" #include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" -#define NB_NR_UE_MAC_INST 1 -/*!\brief Maximum number of logical channl group IDs */ +// ========== +// NR UE defs +// ========== +#define NB_NR_UE_MAC_INST 1 +#define MAX_NUM_BWP 2 +#define NUM_SLOT_FRAME 10 /*!\brief value for indicating BSR Timer is not running */ #define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) +// ================================================ +// SSB to RO mapping private defines and structures +// ================================================ +#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD (16) // Maximum association period is 16 +#define MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max association pattern period is 160ms and minimum PRACH configuration period is 10ms +#define MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD (16) // Max nb of association periods in an association pattern period of 160ms +#define MAX_NB_FRAME_IN_PRACH_CONF_PERIOD (16) // Max PRACH configuration period is 160ms and frame is 10ms +#define MAX_NB_SLOT_IN_FRAME (160) // Max number of slots in a frame (@ SCS 240kHz = 160) +#define MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD (16) // Maximum number of frames in the maximum association pattern period +#define MAX_NB_SSB (64) // Maximum number of possible SSB indexes +#define MAX_RO_PER_SSB (8) // Maximum number of consecutive ROs that can be mapped to an SSB according to the ssb_per_RACH config + +// Maximum number of ROs that can be mapped to an SSB in an association pattern +// This is to reserve enough elements in the SSBs list for each mapped ROs for a single SSB +// An arbitrary maximum number is chosen to be safe: maximum number of slots in an association pattern * maximum number of ROs in a slot +#define MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN (MAX_TDM*MAX_FDM*MAX_NB_SLOT_IN_FRAME*MAX_NB_FRAME_IN_ASSOCIATION_PATTERN_PERIOD) + +// =============== +// DCI fields defs +// =============== + +#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 + +/*!\brief UE layer 2 status */ typedef enum { - SFN_C_MOD_2_EQ_0, - SFN_C_MOD_2_EQ_1, - SFN_C_IMPOSSIBLE -} SFN_C_TYPE; + UE_CONNECTION_OK = 0, + UE_CONNECTION_LOST, + UE_PHY_RESYNCH, + UE_PHY_HO_PRACH +} NR_UE_L2_STATE_t; // LTE structure, might need to be adapted for NR typedef struct { @@ -145,9 +232,6 @@ typedef struct { int16_t bucket_size[NR_MAX_NUM_LCID]; } NR_UE_SCHEDULING_INFO; - -#define MAX_NUM_BWP 2 - typedef enum { RA_UE_IDLE = 0, WAIT_RAR = 1, @@ -155,12 +239,76 @@ typedef enum { RA_SUCCEEDED = 3 } RA_state_t; +typedef struct { + + // pointer to RACH config dedicated + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated; + /// state of RA procedure + RA_state_t ra_state; + /// RA contention type + uint8_t cfra; + /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB. + uint8_t RA_offset; + /// RA-rnti + uint16_t ra_rnti; + /// Temporary CRNTI + uint16_t t_crnti; + /// number of attempt for rach + uint8_t RA_attempt_number; + /// Random-access procedure flag + uint8_t RA_active; + /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot + uint8_t generate_nr_prach; + + /// Random-access window counter + int16_t RA_window_cnt; + /// Flag to monitor if matching RAPID was received in RAR + uint8_t RA_RAPID_found; + /// Flag to monitor if BI was received in RAR + uint8_t RA_BI_found; + /// Random-access backoff counter + int16_t RA_backoff_indicator; + /// Flag to indicate whether preambles Group A was used + uint8_t RA_usedGroupA; + /// RA backoff counter + int16_t RA_backoff_cnt; + /// RA max number of preamble transmissions + int preambleTransMax; + /// Nb of preambles per SSB + long cb_preambles_per_ssb; + int starting_preamble_nb; + + /// Received TPC command (in dB) from RAR + int8_t Msg3_TPC; + /// Flag to indicate whether it is the first Msg3 to be transmitted + uint8_t first_Msg3; + /// RA Msg3 size in bytes + uint8_t Msg3_size; + + /// Random-access Contention Resolution Timer active flag + uint8_t RA_contention_resolution_timer_active; + /// Random-access Contention Resolution Timer count value + uint8_t RA_contention_resolution_cnt; + + /// BeamfailurerecoveryConfig + NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig; + +} RA_config_t; + +typedef struct { + + uint8_t freq_hopping; + uint8_t mcs; + uint8_t Msg3_t_alloc; + uint16_t Msg3_f_alloc; + +} RAR_grant_t; + /*!\brief Top level UE MAC structure */ typedef struct { NR_ServingCellConfigCommon_t *scc; NR_CellGroupConfig_t *scg; - NR_RACH_ConfigDedicated_t *rach_ConfigDedicated; int servCellIndex; NR_CSI_ReportConfig_t *csirc; //// MAC config @@ -177,6 +325,12 @@ typedef struct { 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]; + /*BWP*/ + // dedicated active DL BWP + NR_BWP_Id_t DL_BWP_Id; + // dedicated active UL BWP + NR_BWP_Id_t UL_BWP_Id; + /// Type0-PDCCH seach space fapi_nr_dl_config_dci_dl_pdu_rel15_t type0_pdcch_dci_config; uint32_t type0_pdcch_ss_mux_pattern; @@ -189,70 +343,18 @@ typedef struct { CCCH_PDU CCCH_pdu; ULSCH_PDU ulsch_pdu; - /* Random Access parameters */ - /// state of RA procedure - RA_state_t ra_state; - /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB. - uint8_t RA_offset; - /// RA-rnti - uint16_t ra_rnti; - /// Temporary CRNTI - uint16_t t_crnti; + /* Random Access */ /// CRNTI uint16_t crnti; - /// number of attempt for rach - uint8_t RA_attempt_number; - /// Random-access procedure flag - uint8_t RA_active; - /// Random-access window counter - int8_t RA_window_cnt; - /// Random-access Msg3 size in bytes - uint8_t RA_Msg3_size; - /// Random-access prachMaskIndex - uint8_t RA_prachMaskIndex; - /// Flag indicating Preamble set (A,B) used for first Msg3 transmission - uint8_t RA_usedGroupA; - /// BeamfailurerecoveryConfig - NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig; - /// Preamble Tx Counter - uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER; - /// Preamble Power Ramping Counter - uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER; - /// Random-access backoff counter - int16_t RA_backoff_indicator; - /// Random-access backoff counter - int16_t RA_backoff_cnt; - /// Random-access variable for window calculation (frame of last change in window counter) - uint32_t RA_tx_frame; - /// Random-access variable for window calculation (subframe of last change in window counter) - uint8_t RA_tx_subframe; - /// Scheduled TX frame for RA Msg3 - frame_t msg3_frame; - /// Scheduled TX slot for RA Msg3 - slot_t msg3_slot; - /// Random-access variable for backoff (frame of last change in backoff counter) - uint32_t RA_backoff_frame; - /// Random-access variable for backoff (subframe of last change in backoff counter) - uint8_t RA_backoff_subframe; - /// Random-access Group B maximum path-loss - uint16_t RA_maxPL; - /// Random-access Contention Resolution Timer active flag - uint8_t RA_contention_resolution_timer_active; - /// Random-access Contention Resolution Timer count value - uint8_t RA_contention_resolution_cnt; - /// Msg3 Delta Preamble - int8_t deltaPreamble_Msg3; - /// Received TPC command (in dB) from RAR - int8_t Msg3_TPC; - /// Flag to monitor if matching RAPID was received in RAR - uint8_t RA_RAPID_found; - /// Flag to monitor if BI was received in RAR - uint8_t RA_BI_found; - /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot - uint8_t generate_nr_prach; + /// RA configuration + RA_config_t ra; + /// SSB index from MIB decoding + uint8_t mib_ssb; + /// Last NDI of UL HARQ processes + uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES]; //// FAPI-like interface message - fapi_nr_ul_config_request_t ul_config_request; + fapi_nr_ul_config_request_t *ul_config_request; fapi_nr_dl_config_request_t dl_config_request; /// Interface module instances @@ -265,6 +367,11 @@ typedef struct { /// PHR uint8_t PHR_reporting_active; + + NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; + NR_SearchSpace_t *search_space_zero; + NR_ControlResourceSet_t *coreset0; + } NR_UE_MAC_INST_t; typedef enum seach_space_mask_e { @@ -275,28 +382,6 @@ typedef enum seach_space_mask_e { type3_pdcch = 0x10 } search_space_mask_t; -typedef enum subcarrier_spacing_e { - scs_15kHz = 0x1, - scs_30kHz = 0x2, - scs_60kHz = 0x4, - scs_120kHz = 0x8, - scs_240kHz = 0x16 -} subcarrier_spacing_t; - -typedef enum channel_bandwidth_e { - bw_5MHz = 0x1, - bw_10MHz = 0x2, - bw_20MHz = 0x4, - bw_40MHz = 0x8, - bw_80MHz = 0x16, - bw_100MHz = 0x32 -} channel_bandwidth_t; - -typedef enum frequency_range_e { - FR1 = 0, - 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] @@ -369,67 +454,42 @@ typedef struct { uint8_t reserved_nr_dci ; // 55 RESERVED_NR_DCI } nr_dci_pdu_rel15_t; -#define NUM_SLOT_FRAME 10 +// The PRACH Config period is a series of selected slots in one or multiple frames +typedef struct prach_conf_period { + prach_occasion_slot_t prach_occasion_slot_map[MAX_NB_FRAME_IN_PRACH_CONF_PERIOD][MAX_NB_SLOT_IN_FRAME]; + uint16_t nb_of_prach_occasion; // Total number of PRACH occasions in the PRACH Config period + uint8_t nb_of_frame; // Size of the PRACH Config period in number of 10ms frames + uint8_t nb_of_slot; // Nb of slots in each frame +} prach_conf_period_t; -#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 +// The association period is a series of PRACH Config periods +typedef struct prach_association_period { + prach_conf_period_t *prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PERIOD]; + uint8_t nb_of_prach_conf_period; // Nb of PRACH configuration periods within the association period + uint8_t nb_of_frame; // Total number of frames included in the association period +} prach_association_period_t; -#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 +// The association pattern is a series of Association periods +typedef struct prach_association_pattern { + prach_association_period_t prach_association_period_list[MAX_NB_ASSOCIATION_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD]; + prach_conf_period_t prach_conf_period_list[MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD]; + uint8_t nb_of_assoc_period; // Nb of association periods within the association pattern + uint8_t nb_of_prach_conf_period_in_max_period; // Nb of PRACH configuration periods within the maximum association pattern period (according to the size of the configured PRACH + uint8_t nb_of_frame; // Total number of frames included in the association pattern period (after mapping the SSBs and determining the real association pattern length) +} prach_association_pattern_t; + +// SSB details +typedef struct ssb_info { + boolean_t transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration + prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index + uint16_t nb_mapped_ro; // Total number of mapped ROs to this SSB index +} ssb_info_t; + +// List of all the possible SSBs and their details +typedef struct ssb_list_info { + ssb_info_t tx_ssb[MAX_NB_SSB]; + uint8_t nb_tx_ssb; +} ssb_list_info_t; /*@}*/ #endif /*__LAYER2_MAC_DEFS_H__ */ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_extern.h b/openair2/LAYER2/NR_MAC_UE/mac_extern.h index 54cdc4d149..e551790f7a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_extern.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_extern.h @@ -34,62 +34,53 @@ //extern NR_UE_MAC_INST_t *UE_mac_inst; -// Type0-PDCCH search space -extern const int32_t table_38213_13_1_c2[16]; -extern const int32_t table_38213_13_1_c3[16]; -extern const int32_t table_38213_13_1_c4[16]; - -extern const int32_t table_38213_13_2_c2[16]; -extern const int32_t table_38213_13_2_c3[16]; -extern const int32_t table_38213_13_2_c4[16]; - -extern const int32_t table_38213_13_3_c2[16]; -extern const int32_t table_38213_13_3_c3[16]; -extern const int32_t table_38213_13_3_c4[16]; - -extern const int32_t table_38213_13_4_c2[16]; -extern const int32_t table_38213_13_4_c3[16]; -extern const int32_t table_38213_13_4_c4[16]; - -extern const int32_t table_38213_13_5_c2[16]; -extern const int32_t table_38213_13_5_c3[16]; -extern const int32_t table_38213_13_5_c4[16]; - -extern const int32_t table_38213_13_6_c2[16]; -extern const int32_t table_38213_13_6_c3[16]; -extern const int32_t table_38213_13_6_c4[16]; - -extern const int32_t table_38213_13_7_c2[16]; -extern const int32_t table_38213_13_7_c3[16]; -extern const int32_t table_38213_13_7_c4[16]; - -extern const int32_t table_38213_13_8_c2[16]; -extern const int32_t table_38213_13_8_c3[16]; -extern const int32_t table_38213_13_8_c4[16]; - -extern const int32_t table_38213_13_9_c2[16]; -extern const int32_t table_38213_13_9_c3[16]; -extern const int32_t table_38213_13_9_c4[16]; - -extern const int32_t table_38213_13_10_c2[16]; -extern const int32_t table_38213_13_10_c3[16]; -extern const int32_t table_38213_13_10_c4[16]; - -extern const float table_38213_13_11_c1[16]; -extern const int32_t table_38213_13_11_c2[16]; -extern const float table_38213_13_11_c3[16]; -extern const int32_t table_38213_13_11_c4[16]; - -extern const float table_38213_13_12_c1[16]; -extern const int32_t table_38213_13_12_c2[16]; -extern const float table_38213_13_12_c3[16]; - -extern const int32_t table_38213_10_1_1_c2[5]; - // DCI extraction // for PUSCH from TS 38.214 subclause 6.1.2.1.1 extern uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]; // for PDSCH from TS 38.214 subclause 5.1.2.1.1 extern uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]; +extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; + +// DCI +extern const uint8_t table_7_3_1_1_2_2_3_4_5[64][20]; +extern const uint8_t table_7_3_1_1_2_12[14][3]; +extern const uint8_t table_7_3_1_1_2_13[10][4]; +extern const uint8_t table_7_3_1_1_2_14[3][5]; +extern const uint8_t table_7_3_1_1_2_15[4][6]; +extern const uint8_t table_7_3_1_1_2_16[12][2]; +extern const uint8_t table_7_3_1_1_2_17[7][3]; +extern const uint8_t table_7_3_1_1_2_18[3][4]; +extern const uint8_t table_7_3_1_1_2_19[2][5]; +extern const uint8_t table_7_3_1_1_2_20[28][3]; +extern const uint8_t table_7_3_1_1_2_21[19][4]; +extern const uint8_t table_7_3_1_1_2_22[6][5]; +extern const uint8_t table_7_3_1_1_2_23[5][6]; +extern const uint8_t table_7_3_2_3_3_1[12][5]; +extern const uint8_t table_7_3_2_3_3_2_oneCodeword[31][6]; +extern const uint8_t table_7_3_2_3_3_2_twoCodeword[4][10]; +extern const uint8_t table_7_3_2_3_3_3_oneCodeword[24][5]; +extern const uint8_t table_7_3_2_3_3_3_twoCodeword[2][7]; +extern const uint8_t table_7_3_2_3_3_4_oneCodeword[58][6]; +extern const uint8_t table_7_3_2_3_3_4_twoCodeword[6][10]; + +extern const uint16_t table_7_2_1[16]; + extern dci_pdu_rel15_t *def_dci_pdu_rel15; + +extern dci_pdu_rel15_t *def_dci_pdu_rel15; + +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); + +extern const char *rnti_types[]; +extern const char *dci_formats[]; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 4126b19b0b..c4909c1384 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -34,11 +34,9 @@ #define __LAYER2_MAC_UE_PROTO_H__ #include "mac_defs.h" -#include "mac.h" #include "PHY/defs_nr_UE.h" #include "RRC/NR_UE/rrc_defs.h" - /**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message \param module_id module id \param cc_id component carrier id @@ -58,6 +56,19 @@ int8_t nr_ue_decode_mib( void *pduP, uint16_t cell_id ); +/**\brief decode sib1 pdu in NR_UE, from if_module dl_ind + \param module_id module id + \param cc_id component carrier id + \param gNB_index gNB index + \param sibs_mask sibs mask + \param pduP pointer to pdu + \param pdu_length length of pdu */ +int8_t nr_ue_decode_sib1(module_id_t module_id, + int cc_id, + unsigned int gNB_index, + uint32_t sibs_mask, + uint8_t *pduP, + uint32_t pdu_len); /**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config) \param module_id module id @@ -96,7 +107,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in @param module_id_t mod_id module ID @param int cc_id CC ID @param frame_t frame frame number - @param int slot reference number */ + @param int slot reference number + @param UE_nr_rxtx_proc_t *proc pointer to process context */ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, fapi_nr_dl_config_request_t *dl_config, fapi_nr_ul_config_request_t *ul_config, @@ -104,7 +116,8 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, module_id_t mod_id, int cc_id, frame_t frame, - int slot); + int slot, + int thread_id); /* \brief Get SR payload (0,1) from UE MAC @param Mod_id Instance id of UE in machine @@ -119,43 +132,26 @@ 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, 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); +int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format); +int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); uint32_t get_ssb_frame(uint32_t test); -uint32_t get_ssb_slot(uint32_t ssb_index); - uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe); /* \brief Get payload (MAC PDU) from UE PHY -@param module_idP Instance id of UE in machine -@param CC_id Component Carrier index -@param frameP Current Rx frame -@param slotP Current Rx slot -@param pdu Pointer to the MAC PDU -@param pdu_len Length of the MAC PDU -@param gNB_id Index of gNB that UE is attached to -@param ul_time_alignment of struct handling the timing advance parameters +@param dl_info pointer to dl indication +@param ul_time_alignment pointer to timing advance parameters +@param pdu_id index of DL PDU @returns void */ -void nr_ue_send_sdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - int slotP, - uint8_t * pdu, - uint16_t pdu_len, - uint8_t gNB_index, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); - -void nr_ue_process_mac_pdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - uint8_t *pduP, - uint16_t mac_pdu_len, - uint8_t gNB_index, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); +void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, + int pdu_id); +void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, + int pdu_id); uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, uint8_t *pdu, @@ -170,17 +166,19 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, unsigned short post_padding, uint16_t buflen); -int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len); - void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t 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, - dci_pdu_rel15_t *nr_pdci_info_extracted); +uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, + uint8_t dci_format, + uint8_t dci_length, + uint16_t rnti, + uint64_t *dci_pdu, + dci_pdu_rel15_t *nr_pdci_info_extracted); +int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, + uint8_t time_domain_ind); uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, @@ -204,6 +202,11 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m */ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format); +/** \brief Function to compute configured maximum output power according to clause 6.2.4 of 3GPP TS 38.101-1 version 16.5.0 Release 16 + @param Mod_id Module id of UE +*/ +long nr_get_Pcmax(module_id_t mod_id); + /* Random Access */ /* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x @@ -211,9 +214,10 @@ and fills the PRACH PDU per each FD occasion. @param module_idP Index of UE instance @param frameP Frame index @param slotP Slot index +@param thread_id RX/TX Thread ID @returns void */ -void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id); /* \brief This function schedules the Msg3 transmission @param @@ -238,22 +242,15 @@ random-access procedure @param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload @returns timing advance or 0xffff if preamble doesn't match */ -uint16_t nr_ue_process_rar(module_id_t mod_id, - int CC_id, - frame_t frameP, - sub_frame_t slotP, - uint8_t * dlsch_buffer, - rnti_t * t_crnti, - uint8_t preamble_index, - uint8_t * selected_rar_buffer); +int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id); void nr_process_rar(nr_downlink_indication_t *dl_info); -void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame); +void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources); -void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); +void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot); -void nr_ra_succeeded(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); +void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot); /* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC @@ -264,29 +261,27 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 @param CC_id Component Carrier Index @param frame @param gNB_id gNB index -@param nr_tti_tx slot for PRACH transmission +@param nr_slot_tx slot for PRACH transmission @returns indication to generate PRACH to phy */ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, - UE_MODE_t UE_mode, frame_t frame, uint8_t gNB_id, - int nr_tti_tx); + int nr_slot_tx); /* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321). @param module_idP Index of UE instance @param CC_id Component Carrier Index @param gNB_index gNB index -@param t_id @param rach_ConfigDedicated @returns void */ void nr_get_prach_resources(module_id_t mod_id, int CC_id, uint8_t gNB_id, - uint8_t t_id, - uint8_t first_Msg3, NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated); void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id); @@ -305,5 +300,37 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, uint8_t *nb_dmrs_re_per_rb, uint16_t *number_dmrs_symbols); +void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired); + +void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format); + +fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot); + +void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); + +// PUSCH scheduler: +// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, +// - where K2 is the offset between the slot in which UL DCI is received and the slot +// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. +// PUSCH Msg3 scheduler: +// - scheduled by RAR UL grant according to 8.3 of TS 38.213 +int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, uint8_t is_Msg3, frame_t current_frame, int current_slot, frame_t *frame_tx, int *slot_tx, uint8_t tda_id); + +int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti); + +// Configuration of Msg3 PDU according to clauses: +// - 8.3 of 3GPP TS 38.213 version 16.3.0 Release 16 +// - 6.1.2.2 of TS 38.214 +// - 6.1.3 of TS 38.214 +// - 6.2.2 of TS 38.214 +// - 6.1.4.2 of TS 38.214 +// - 6.4.1.1.1 of TS 38.211 +// - 6.3.1.7 of 38.211 +int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, + dci_pdu_rel15_t *dci, + RAR_grant_t *rar_grant, + uint16_t rnti, + uint8_t *dci_format); #endif /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_vars.c b/openair2/LAYER2/NR_MAC_UE/mac_vars.c index 95dea61a45..ecabdb870c 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_vars.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_vars.c @@ -30,106 +30,404 @@ * \warning */ -#include "mac_defs.h" +#include -#define reserved 0xffff +const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"}; +const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"}; -// specification mapping talbe, table_38$x_$y_$z_c$a -// - $x: specification -// - $y: subclause-major -// - $z: subclause-minor -// - $a: ($a)th of column in table, start from zero -const int32_t table_38213_13_1_c2[16] = {24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 96, 96, 96, reserved}; // index 15 reserved -const int32_t table_38213_13_1_c3[16] = { 2, 2, 2, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved}; // index 15 reserved -const int32_t table_38213_13_1_c4[16] = { 0, 2, 4, 0, 2, 4, 12, 16, 12, 16, 12, 16, 38, 38, 38, reserved}; // index 15 reserved +// table_7_3_1_1_2_2_3_4_5 contains values for number of layers and precoding information for tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2 +// the first 6 columns contain table 7.3.1.1.2-2: Precoding information and number of layers, for 4 antenna ports, if transformPrecoder=disabled and maxRank = 2 or 3 or 4 +// next six columns contain table 7.3.1.1.2-3: Precoding information and number of layers for 4 antenna ports, if transformPrecoder= enabled, or if transformPrecoder=disabled and maxRank = 1 +// next four columns contain table 7.3.1.1.2-4: Precoding information and number of layers, for 2 antenna ports, if transformPrecoder=disabled and maxRank = 2 +// next four columns contain table 7.3.1.1.2-5: Precoding information and number of layers, for 2 antenna ports, if transformPrecoder= enabled, or if transformPrecoder= disabled and maxRank = 1 +const uint8_t table_7_3_1_1_2_2_3_4_5[64][20] = { + {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}, + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 0, 2, 0, 1, 2, 0, 0}, + {1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 2, 0, 0, 1, 3, 0, 0}, + {2, 0, 2, 0, 2, 0, 1, 4, 1, 4, 0, 0, 1, 3, 0, 0, 1, 4, 0, 0}, + {2, 1, 2, 1, 2, 1, 1, 5, 1, 5, 0, 0, 1, 4, 0, 0, 1, 5, 0, 0}, + {2, 2, 2, 2, 2, 2, 1, 6, 1, 6, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0}, + {2, 3, 2, 3, 2, 3, 1, 7, 1, 7, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0}, + {2, 4, 2, 4, 2, 4, 1, 8, 1, 8, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0}, + {2, 5, 2, 5, 2, 5, 1, 9, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 0, 3, 0, 3, 0, 1, 10, 1, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 0, 4, 0, 4, 0, 1, 11, 1, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 4, 1, 4, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 5, 1, 5, 0, 0, 1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 6, 1, 6, 0, 0, 1, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 7, 1, 7, 0, 0, 1, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 8, 1, 8, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 9, 1, 9, 0, 0, 1, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 10, 1, 10, 0, 0, 1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 11, 1, 11, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 6, 2, 6, 0, 0, 1, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 7, 2, 7, 0, 0, 1, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 8, 2, 8, 0, 0, 1, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 9, 2, 9, 0, 0, 1, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 10, 2, 10, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 11, 2, 11, 0, 0, 1, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 12, 2, 12, 0, 0, 1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 13, 2, 13, 0, 0, 1, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 1, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 2, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {2, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {3, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {4, 4, 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} +}; -const int32_t table_38213_13_2_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved}; // index 14-15 reserved -const int32_t table_38213_13_2_c3[16] = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved}; // index 14-15 reserved -const int32_t table_38213_13_2_c4[16] = { 5, 6, 7, 8, 5, 6, 7, 8, 18, 20, 18, 20, 18, 20, reserved, reserved}; // index 14-15 reserved +const uint8_t table_7_3_1_1_2_12[14][3] = { + {1,0,1}, + {1,1,1}, + {2,0,1}, + {2,1,1}, + {2,2,1}, + {2,3,1}, + {2,0,2}, + {2,1,2}, + {2,2,2}, + {2,3,2}, + {2,4,2}, + {2,5,2}, + {2,6,2}, + {2,7,2} +}; -const int32_t table_38213_13_3_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved -const int32_t table_38213_13_3_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved -const int32_t table_38213_13_3_c4[16] = { 2, 6, 2, 6, 2, 6, 28, 28, 28, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const uint8_t table_7_3_1_1_2_13[10][4] = { + {1,0,1,1}, + {2,0,1,1}, + {2,2,3,1}, + {2,0,2,1}, + {2,0,1,2}, + {2,2,3,2}, + {2,4,5,2}, + {2,6,7,2}, + {2,0,4,2}, + {2,2,6,2} +}; -const int32_t table_38213_13_4_c2[16] = {24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48}; -const int32_t table_38213_13_4_c3[16] = { 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 2}; -const int32_t table_38213_13_4_c4[16] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 12, 14, 16, 12, 14, 16}; +const uint8_t table_7_3_1_1_2_14[3][5] = { + {2,0,1,2,1}, + {2,0,1,4,2}, + {2,2,3,6,2} +}; -const int32_t table_38213_13_5_c2[16] = {48, 48, 48, 96, 96, 96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved -const int32_t table_38213_13_5_c3[16] = { 1, 2, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved -const int32_t table_38213_13_5_c4[16] = { 4, 4, 4, 0, 56, 0, 56, 0, 56, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 09-15 reserved +const uint8_t table_7_3_1_1_2_15[4][6] = { + {2,0,1,2,3,1}, + {2,0,1,4,5,2}, + {2,2,3,6,7,2}, + {2,0,2,4,6,2} +}; -const int32_t table_38213_13_6_c2[16] = {24, 24, 24, 24, 48, 48, 48, 48, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved -const int32_t table_38213_13_6_c3[16] = { 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved -const int32_t table_38213_13_6_c4[16] = { 0, 4, 0, 4, 0, 28, 0, 28, 0, 28, reserved, reserved, reserved, reserved, reserved, reserved}; // index 10-15 reserved +const uint8_t table_7_3_1_1_2_16[12][2] = { + {1,0}, + {1,1}, + {2,0}, + {2,1}, + {2,2}, + {2,3}, + {3,0}, + {3,1}, + {3,2}, + {3,3}, + {3,4}, + {3,5} +}; -const int32_t table_38213_13_7_c2[16] = {48, 48, 48, 48, 48, 48, 96, 96, 48, 48, 96, 96, reserved, reserved, reserved, reserved}; // index 12-15 reserved -const int32_t table_38213_13_7_c3[16] = { 1, 1, 2, 2, 3, 3, 1, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved}; // index 12-15 reserved -const int32_t table_38213_13_7_c4[16] = { 0, 8, 0, 8, 0, 8, 28, 28,-41, 49,-41, 97, reserved, reserved, reserved, reserved}; // index 12-15 reserved, condition A as default +const uint8_t table_7_3_1_1_2_17[7][3] = { + {1,0,1}, + {2,0,1}, + {2,2,3}, + {3,0,1}, + {3,2,3}, + {3,4,5}, + {2,0,2} +}; -const int32_t table_38213_13_8_c2[16] = { 1, 1, 1, 1, 3, 3, 3, 3, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved -const int32_t table_38213_13_8_c3[16] = {24, 24, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved -const int32_t table_38213_13_8_c4[16] = { 0, 4, 14, 14,-20, 24,-20, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 15 reserved, condition A as default +const uint8_t table_7_3_1_1_2_18[3][4] = { + {2,0,1,2}, + {3,0,1,2}, + {3,3,4,5} +}; -const int32_t table_38213_13_9_c2[16] = {96, 96, 96, 96, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved -const int32_t table_38213_13_9_c3[16] = { 1, 1, 2, 2, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved -const int32_t table_38213_13_9_c4[16] = { 0, 16, 0, 16, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 04-15 reserved +const uint8_t table_7_3_1_1_2_19[2][5] = { + {2,0,1,2,3}, + {3,0,1,2,3} +}; -const int32_t table_38213_13_10_c2[16] = {48, 48, 48, 48, 24, 24, 48, 48, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved -const int32_t table_38213_13_10_c3[16] = { 1, 1, 2, 2, 1, 1, 1, 1, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved -const int32_t table_38213_13_10_c4[16] = { 0, 8, 0, 8,-41, 25,-41, 49, reserved, reserved, reserved, reserved, reserved, reserved, reserved, reserved}; // index 08-15 reserved, condition A as default +const uint8_t table_7_3_1_1_2_20[28][3] = { + {1,0,1}, + {1,1,1}, + {2,0,1}, + {2,1,1}, + {2,2,1}, + {2,3,1}, + {3,0,1}, + {3,1,1}, + {3,2,1}, + {3,3,1}, + {3,4,1}, + {3,5,1}, + {3,0,2}, + {3,1,2}, + {3,2,2}, + {3,3,2}, + {3,4,2}, + {3,5,2}, + {3,6,2}, + {3,7,2}, + {3,8,2}, + {3,9,2}, + {3,10,2}, + {3,11,2}, + {1,0,2}, + {1,1,2}, + {1,6,2}, + {1,7,2} +}; -const float table_38213_13_11_c1[16] = { 0, 0, 2, 2, 5, 5, 7, 7, 0, 5, 0, 0, 2, 2, 5, 5}; // O -const int32_t table_38213_13_11_c2[16] = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1}; -const float table_38213_13_11_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 0.5f, 1, 1, 1, 1, 1, 1, 1, 1}; // M -const int32_t table_38213_13_11_c4[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2}; // i is even as default +const uint8_t table_7_3_1_1_2_21[19][4] = { + {1,0,1,1}, + {2,0,1,1}, + {2,2,3,1}, + {3,0,1,1}, + {3,2,3,1}, + {3,4,5,1}, + {2,0,2,1}, + {3,0,1,2}, + {3,2,3,2}, + {3,4,5,2}, + {3,6,7,2}, + {3,8,9,2}, + {3,10,11,2}, + {1,0,1,2}, + {1,6,7,2}, + {2,0,1,2}, + {2,2,3,2}, + {2,6,7,2}, + {2,8,9,2} +}; -const float table_38213_13_12_c1[16] = { 0, 0, 2.5f, 2.5f, 5, 5, 0, 2.5f, 5, 7.5f, 7.5f, 7.5f, 0, 5, reserved, reserved}; // O, index 14-15 reserved -const int32_t table_38213_13_12_c2[16] = { 1, 2, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, reserved, reserved}; // index 14-15 reserved -const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f, 0.5f, 1, 0.5f, 0.5f, 1, 1, reserved, reserved}; // M, index 14-15 reserved +const uint8_t table_7_3_1_1_2_22[6][5] = { + {2,0,1,2,1}, + {3,0,1,2,1}, + {3,3,4,5,1}, + {3,0,1,6,2}, + {3,2,3,8,2}, + {3,4,5,10,2} +}; -const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 }; +const uint8_t table_7_3_1_1_2_23[5][6] = { + {2,0,1,2,3,1}, + {3,0,1,2,3,1}, + {3,0,1,6,7,2}, + {3,2,3,8,9,2}, + {3,4,5,10,11,2} +}; -/* - #define mu_pusch 1 -// definition table j Table 6.1.2.1.1-4 - #define j ((mu_pusch==3)?3:(mu_pusch==2)?2:1) - uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1 - {j, 0,14}, // row index 1 - {j, 0,12}, // row index 2 - {j, 0,10}, // row index 3 - {j, 2,10}, // row index 4 - {j, 4,10}, // row index 5 - {j, 4,8}, // row index 6 - {j, 4,6}, // row index 7 - {j+1,0,14}, // row index 8 - {j+1,0,12}, // row index 9 - {j+1,0,10}, // row index 10 - {j+2,0,14}, // row index 11 - {j+2,0,12}, // row index 12 - {j+2,0,10}, // row index 13 - {j, 8,6}, // row index 14 - {j+3,0,14}, // row index 15 - {j+3,0,10} // row index 16 - }; +const uint8_t table_7_3_2_3_3_1[12][5] = { + {1,0,0,0,0}, + {1,1,0,0,0}, + {1,0,1,0,0}, + {2,0,0,0,0}, + {2,1,0,0,0}, + {2,2,0,0,0}, + {2,3,0,0,0}, + {2,0,1,0,0}, + {2,2,3,0,0}, + {2,0,1,2,0}, + {2,0,1,2,3}, + {2,0,2,0,0} +}; - #define dmrs_typeA_pos 2 - uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 - {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?12:11}, // row index 1 - {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?10:9}, // row index 2 - {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?9:8}, // row index 3 - {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?7:6}, // row index 4 - {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?5:4}, // row index 5 - {0,(dmrs_typeA_pos == 2)?9:10,(dmrs_typeA_pos == 2)?4:4}, // row index 6 - {0,(dmrs_typeA_pos == 2)?4:6, (dmrs_typeA_pos == 2)?4:4}, // row index 7 - {0,5,7}, // row index 8 - {0,5,2}, // row index 9 - {0,9,2}, // row index 10 - {0,12,2}, // row index 11 - {0,1,13}, // row index 12 - {0,1,6}, // row index 13 - {0,2,4}, // row index 14 - {0,4,7}, // row index 15 - {0,8,4} // row index 16 - }; -*/ +const uint8_t table_7_3_2_3_3_2_oneCodeword[31][6] = { + {1,0,0,0,0,1}, + {1,1,0,0,0,1}, + {1,0,1,0,0,1}, + {2,0,0,0,0,1}, + {2,1,0,0,0,1}, + {2,2,0,0,0,1}, + {2,3,0,0,0,1}, + {2,0,1,0,0,1}, + {2,2,3,0,0,1}, + {2,0,1,2,0,1}, + {2,0,1,2,3,1}, + {2,0,2,0,0,1}, + {2,0,0,0,0,2}, + {2,1,0,0,0,2}, + {2,2,0,0,0,2}, + {2,3,0,0,0,2}, + {2,4,0,0,0,2}, + {2,5,0,0,0,2}, + {2,6,0,0,0,2}, + {2,7,0,0,0,2}, + {2,0,1,0,0,2}, + {2,2,3,0,0,2}, + {2,4,5,0,0,2}, + {2,6,7,0,0,2}, + {2,0,4,0,0,2}, + {2,2,6,0,0,2}, + {2,0,1,4,0,2}, + {2,2,3,6,0,2}, + {2,0,1,4,5,2}, + {2,2,3,6,7,2}, + {2,0,2,4,6,2} +}; + +const uint8_t table_7_3_2_3_3_2_twoCodeword[4][10] = { + {2,0,1,2,3,4,0,0,0,2}, + {2,0,1,2,3,4,6,0,0,2}, + {2,0,1,2,3,4,5,6,0,2}, + {2,0,1,2,3,4,5,6,7,2} +}; + +const uint8_t table_7_3_2_3_3_3_oneCodeword[24][5] = { + {1,0,0,0,0}, + {1,1,0,0,0}, + {1,0,1,0,0}, + {2,0,0,0,0}, + {2,1,0,0,0}, + {2,2,0,0,0}, + {2,3,0,0,0}, + {2,0,1,0,0}, + {2,2,3,0,0}, + {2,0,1,2,0}, + {2,0,1,2,3}, + {3,0,0,0,0}, + {3,1,0,0,0}, + {3,2,0,0,0}, + {3,3,0,0,0}, + {3,4,0,0,0}, + {3,5,0,0,0}, + {3,0,1,0,0}, + {3,2,3,0,0}, + {3,4,5,0,0}, + {3,0,1,2,0}, + {3,3,4,5,0}, + {3,0,1,2,3}, + {2,0,2,0,0} +}; + +const uint8_t table_7_3_2_3_3_3_twoCodeword[2][7] = { + {3,0,1,2,3,4,0}, + {3,0,1,2,3,4,5} +}; + +const uint8_t table_7_3_2_3_3_4_oneCodeword[58][6] = { + {1,0,0,0,0,1}, + {1,1,0,0,0,1}, + {1,0,1,0,0,1}, + {2,0,0,0,0,1}, + {2,1,0,0,0,1}, + {2,2,0,0,0,1}, + {2,3,0,0,0,1}, + {2,0,1,0,0,1}, + {2,2,3,0,0,1}, + {2,0,1,2,0,1}, + {2,0,1,2,3,1}, + {3,0,0,0,0,1}, + {3,1,0,0,0,1}, + {3,2,0,0,0,1}, + {3,3,0,0,0,1}, + {3,4,0,0,0,1}, + {3,5,0,0,0,1}, + {3,0,1,0,0,1}, + {3,2,3,0,0,1}, + {3,4,5,0,0,1}, + {3,0,1,2,0,1}, + {3,3,4,5,0,1}, + {3,0,1,2,3,1}, + {2,0,2,0,0,1}, + {3,0,0,0,0,2}, + {3,1,0,0,0,2}, + {3,2,0,0,0,2}, + {3,3,0,0,0,2}, + {3,4,0,0,0,2}, + {3,5,0,0,0,2}, + {3,6,0,0,0,2}, + {3,7,0,0,0,2}, + {3,8,0,0,0,2}, + {3,9,0,0,0,2}, + {3,10,0,0,0,2}, + {3,11,0,0,0,2}, + {3,0,1,0,0,2}, + {3,2,3,0,0,2}, + {3,4,5,0,0,2}, + {3,6,7,0,0,2}, + {3,8,9,0,0,2}, + {3,10,11,0,0,2}, + {3,0,1,6,0,2}, + {3,2,3,8,0,2}, + {3,4,5,10,0,2}, + {3,0,1,6,7,2}, + {3,2,3,8,9,2}, + {3,4,5,10,11,2}, + {1,0,0,0,0,2}, + {1,1,0,0,0,2}, + {1,6,0,0,0,2}, + {1,7,0,0,0,2}, + {1,0,1,0,0,2}, + {1,6,7,0,0,2}, + {2,0,1,0,0,2}, + {2,2,3,0,0,2}, + {2,6,7,0,0,2}, + {2,8,9,0,0,2} +}; + +const uint8_t table_7_3_2_3_3_4_twoCodeword[6][10] = { + {3,0,1,2,3,4,0,0,0,1}, + {3,0,1,2,3,4,5,0,0,1}, + {2,0,1,2,3,6,0,0,0,2}, + {2,0,1,2,3,6,8,0,0,2}, + {2,0,1,2,3,6,7,8,0,2}, + {2,0,1,2,3,6,7,8,9,2} +}; + +// table 7.2-1 TS 38.321 +const uint16_t table_7_2_1[16] = { + 5, // row index 0 + 10, // row index 1 + 20, // row index 2 + 30, // row index 3 + 40, // row index 4 + 60, // row index 5 + 80, // row index 6 + 120, // row index 7 + 160, // row index 8 + 240, // row index 9 + 320, // row index 10 + 480, // row index 11 + 960, // row index 12 + 1920, // row index 13 +}; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index bae8e0d3c0..bbb44ba47a 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -37,8 +37,6 @@ #include "assertions.h" #include "PHY/types.h" #include "PHY/defs_UE.h" -#include "openair2/LAYER2/RLC/rlc.h" -#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "executables/softmodem-common.h" @@ -54,13 +52,21 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST); if (rrc_inst) { nr_rrc_mac_config_req_ue(0,0,0,NULL,rrc_inst->cell_group_config); - if (IS_SOFTMODEM_NOS1){ - if (rlc_module_init(0) != 0) { - LOG_I(RLC, "Problem at RLC initiation \n"); - } - pdcp_layer_init(); - nr_DRB_preconfiguration(); + AssertFatal(rlc_module_init(0) == 0, "%s: Could not initialize RLC layer\n", __FUNCTION__); + pdcp_layer_init(); + nr_DRB_preconfiguration(nr_ue_mac_inst->crnti); + } + + // Allocate memory for ul_config_request in the mac instance. This is now a pointer and will + // point to a list of structures (one for each UL slot) to store PUSCH scheduling parameters + // received from UL DCI. + if (nr_ue_mac_inst->scc) { + int num_slots_ul = nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if (nr_ue_mac_inst->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) + num_slots_ul++; + LOG_D(MAC, "Initializing ul_config_request. num_slots_ul = %d\n", num_slots_ul); + nr_ue_mac_inst->ul_config_request = (fapi_nr_ul_config_request_t *)calloc(num_slots_ul, sizeof(fapi_nr_ul_config_request_t)); } } else LOG_I(MAC,"Running without RRC instance\n"); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c index 30e4acaf49..27623fe5be 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c @@ -30,10 +30,12 @@ */ #include "PHY/defs_nr_common.h" +//#include "PHY/impl_defs_top.h" #include "mac_defs.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" +#include "NR_P-Max.h" /* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){ @@ -133,21 +135,33 @@ int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_forma return 0; } -/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */ +// TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration +// Measurement units: +// - preambleReceivedTargetPower dBm (-202..-60, 2 dBm granularity) +// - delta_preamble dB +// - RA_PREAMBLE_POWER_RAMPING_STEP dB +// - POWER_OFFSET_2STEP_RA dB +// returns receivedTargerPower in dBm int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; int8_t receivedTargerPower, delta_preamble; - long preambleReceivedTargetPower; + long preambleReceivedTargetPower = 0; - AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id); + if (prach_resources->RA_TYPE == RA_4STEP){ + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; + } else if (prach_resources->RA_TYPE == RA_2STEP){ + // msgA-PreambleReceivedTargetPower + LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__); + } - preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format); - receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (mac->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + prach_resources->POWER_OFFSET_2STEP_RA; + + LOG_D(MAC, "In %s: receivedTargerPower is %d dBm \n", __FUNCTION__, receivedTargerPower); return receivedTargerPower; } @@ -171,3 +185,81 @@ void get_num_re_dmrs(nfapi_nr_ue_pusch_pdu_t *pusch_pdu, *nb_dmrs_re_per_rb = ((dmrs_type == pusch_dmrs_type1) ? 6:4)*cdm_grps_no_data; } + +// Implementation of 6.2.4 Configured ransmitted power +// 3GPP TS 38.101-1 version 16.5.0 Release 16 +// - +// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot. +// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c +// - +// Measurement units: +// - p_max: dBm +// - delta_TC_c: dB +// - P_powerclass: dBm +// - delta_P_powerclass: dB +// - MPR_c: dB +// - delta_MPR_c: dB +// - delta_T_IB_c dB +// - delta_rx_SRS dB +// note: +// - Assuming: +// -- Powerclass 3 capable UE (which is default power class unless otherwise stated) +// -- Maximum power reduction (MPR_c) for power class 3, QPSK, inner RB allocations +// -- no additional MPR (A_MPR_c) +// todo: +// - in current implementation delta_P_powerclass is not handling power classes different from 3 +long nr_get_Pcmax(module_id_t mod_id){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + uint32_t band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + NR_P_Max_t p_max = 0; + uint8_t P_powerclass = 23; + uint8_t delta_P_powerclass = 0; + uint8_t MPR_c = 1.5; + uint8_t delta_MPR_c = 0; + uint8_t A_MPR_c = 0; + uint8_t delta_T_IB_c = 0; + uint8_t delta_TC_c = 0; + uint8_t delta_rx_SRS = 0; + uint8_t P_MPR_c = 0; + long P_cmax_l = 0; + long P_cmax_h = 0; + long P_cmax = 0; + + if (band == 28 && mac->phy_config.config_req.carrier_config.uplink_bandwidth == 30){ + delta_MPR_c = 0.5; + } + + if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){ + if (*mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){ + // TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation + delta_P_powerclass = -3; + p_max += 3; + } + } + + if (mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max){ + + p_max += *mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max; + + LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max); + + P_cmax_l = min(p_max - delta_TC_c, (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c)); + + P_cmax_h = min(p_max, P_powerclass - delta_P_powerclass); + + } else { + + P_cmax_l = (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c); + + P_cmax_h = P_powerclass - delta_P_powerclass; + + } + + P_cmax = (P_cmax_h + P_cmax_l) / 2; + + LOG_D(MAC, "In %s configured maximum output power: %ld dBm <= PCMAX %ld dBm <= %ld dBm \n", __FUNCTION__, P_cmax_l, P_cmax, P_cmax_h); + + return P_cmax; + +} \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 117e5d2970..b4b63e0064 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -30,21 +30,6 @@ * \warning */ -#include "mac.h" - -/* -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "PHY_INTERFACE/phy_interface_extern.h" -#include "SCHED_UE/sched_UE.h" -#include "COMMON/mac_rrc_primitives.h" -#include "RRC/LTE/rrc_extern.h" -#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -#include "common/utils/LOG/log.h" -#include "UTIL/OPT/opt.h" -#include "OCG.h" -#include "OCG_extern.h" -#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/ - /* Tools */ #include "SIMULATION/TOOLS/sim.h" // for taus @@ -62,84 +47,228 @@ #include "NR_MAC_COMMON/nr_mac.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" -extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; -extern const uint8_t nr_slots_per_frame[5]; - -//extern uint8_t nfapi_mode; - void nr_get_RA_window(NR_UE_MAC_INST_t *mac); -// WIP -// This routine implements Section 5.1.2 (UE Random Access Resource Selection) -// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321 -void nr_get_prach_resources(module_id_t mod_id, - int CC_id, - uint8_t gNB_id, - uint8_t t_id, - uint8_t first_Msg3, - NR_PRACH_RESOURCES_t *prach_resources, - NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ +// Random Access procedure initialization as per 5.1.1 and initialization of variables specific +// to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16) +// todo: +// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX (currently hardcoded to 0) +void init_RA(module_id_t mod_id, + NR_PRACH_RESOURCES_t *prach_resources, + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric, + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated) { NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon; - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric; - // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo + RA_config_t *ra = &mac->ra; + ra->RA_active = 1; + ra->RA_RAPID_found = 0; + ra->preambleTransMax = 0; + ra->first_Msg3 = 1; + ra->starting_preamble_nb = 0; + ra->RA_backoff_cnt = 0; - int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0; - uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size; - - AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); - nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric; - - // NR_RSRP_Range_t rsrp_ThresholdSSB; // todo - - /////////////////////////////////////////////////////////// - //////////* UE Random Access Resource Selection *////////// - /////////////////////////////////////////////////////////// - - // todo: - // - switch initialisation cases - // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) - // --- SSB selection, set prach_resources->ra_PreambleIndex - // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 - // --- set PREAMBLE_INDEX to ra_preamble_index - // --- select the SSB signalled by PDCCH - // -- RA initiated for SI request: - // --- SSB selection, set prach_resources->ra_PreambleIndex + prach_resources->RA_PREAMBLE_BACKOFF = 0; + prach_resources->RA_PCMAX = nr_get_Pcmax(mod_id); + prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; + prach_resources->POWER_OFFSET_2STEP_RA = 0; + prach_resources->RA_SCALING_FACTOR_BI = 1; if (rach_ConfigDedicated) { - //////////* Contention free RA *////////// - // - the PRACH preamble for the UE to transmit is set through RRC configuration - // - this is the default mode in current implementation! - // Operation for contention-free RA resources when: - // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection - // - available CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection - // - network controlled Mobility - uint8_t cfra_ssb_resource_idx = 0; - prach_resources->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex; - LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-free random access procedure... \n", prach_resources->ra_PreambleIndex); + if (rach_ConfigDedicated->cfra){ + LOG_I(MAC, "Initialization of 4-step contention-free random access procedure\n"); + prach_resources->RA_TYPE = RA_4STEP; + ra->cfra = 1; + } else if (rach_ConfigDedicated->ext1){ + if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){ + LOG_I(MAC, "In %s: setting RA type to 2-step...\n", __FUNCTION__); + prach_resources->RA_TYPE = RA_2STEP; + ra->cfra = 1; + } else { + LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__); + } + } else { + LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__); + } } else { - //////////* Contention-based RA preamble selection *////////// - // todo: - // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB - // - todo determine next available PRACH occasion + LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__); + } - // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; + if (prach_resources->RA_TYPE == RA_2STEP){ + LOG_E(MAC, "Missing implementation of initialization of 2-step RA specific variables...\n"); + } else if (prach_resources->RA_TYPE == RA_4STEP){ + LOG_D(MAC, "Initialization of 4-step RA specific variables...\n"); + switch (rach_ConfigGeneric->powerRampingStep){ // in dB + case 0: + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0; + break; + case 1: + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2; + break; + case 2: + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4; + break; + case 3: + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6; + break; + } - Msg3_size = mac->RA_Msg3_size; + switch (rach_ConfigGeneric->preambleTransMax) { + case 0: + ra->preambleTransMax = 3; + break; + case 1: + ra->preambleTransMax = 4; + break; + case 2: + ra->preambleTransMax = 5; + break; + case 3: + ra->preambleTransMax = 6; + break; + case 4: + ra->preambleTransMax = 7; + break; + case 5: + ra->preambleTransMax = 8; + break; + case 6: + ra->preambleTransMax = 10; + break; + case 7: + ra->preambleTransMax = 20; + break; + case 8: + ra->preambleTransMax = 50; + break; + case 9: + ra->preambleTransMax = 100; + break; + case 10: + ra->preambleTransMax = 200; + break; + } + if (nr_rach_ConfigCommon->ext1) { + if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){ + LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__); + } + } + } - numberOfRA_Preambles = 64; - if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL) + return; + +} + +void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){ + + // Determine the SSB to RACH mapping ratio + // ======================================= + if (prach_resources->RA_TYPE == RA_4STEP){ + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB + int total_preambles_per_ssb; + uint8_t ssb_nb_in_ro; + int numberOfRA_Preambles = 64; + + switch (ssb_perRACH_config){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 8; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 4; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 2; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 1; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 2; + ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1); + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 4; + ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 8; + ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 16; + ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); + break; + } + + if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles) numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles); + // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration + if ((true == multiple_ssb_per_ro) && + (ssb_rach_ratio > 1)) { + total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio; + + ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro; + ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro; + } + else { + total_preambles_per_ssb = numberOfRA_Preambles; + ra->starting_preamble_nb = 0; + } + } else { + LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__); + } +} + +// This routine implements RA premable configuration according to +// section 5.1 (Random Access procedure) of 3GPP TS 38.321 version 16.2.1 Release 16 +void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac, int16_t dl_pathloss){ + + int messageSizeGroupA = 0; + int sizeOfRA_PreamblesGroupA = 0; + int messagePowerOffsetGroupB = 0; + int PLThreshold; + long deltaPreamble_Msg3 = 0; + uint8_t noGroupB = 0; + RA_config_t *ra = &mac->ra; + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric; + + if (prach_resources->RA_TYPE == RA_4STEP){ + + if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){ + deltaPreamble_Msg3 = (*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB + LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3); + } + if (!nr_rach_ConfigCommon->groupBconfigured) { noGroupB = 1; + LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__); } else { // RA preambles group B is configured - // - Defining the number of RA preambles in RA Preamble Group A for each SSB */ + // - Random Access Preambles group B is configured for 4-step RA type + // - Defining the number of RA preambles in RA Preamble Group A for each SSB + LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__); sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA; switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){ /* - Threshold to determine the groups of RA preambles */ @@ -174,7 +303,7 @@ void nr_get_prach_resources(module_id_t mod_id, messageSizeGroupA = 72; break; default: - AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA); + AssertFatal(1 == 0, "Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA); /* todo cases 10 -15*/ } @@ -209,195 +338,201 @@ void nr_get_prach_resources(module_id_t mod_id, AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); } - // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 - mac->deltaPreamble_Msg3 = 0; - deltaPreamble_Msg3 = mac->deltaPreamble_Msg3; - } + PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; - PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; - - /* Msg3 has not been transmitted yet */ - if (first_Msg3 == 1) { - if (noGroupB == 1) { - // use Group A preamble - prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; - mac->RA_usedGroupA = 1; - } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) { - // Group B is configured and RA preamble Group A is used - // - todo add condition on CCCH_sdu_size for initiation by CCCH - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - mac->RA_usedGroupA = 1; - } else { - // Group B preamble is configured and used - // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A - // the remaining belong to RA Preambles Group B - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - mac->RA_usedGroupA = 0; - } - } else { // Msg3 is being retransmitted - if (mac->RA_usedGroupA == 1 && noGroupB == 1) { - prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; - } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){ - prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; - } else { - prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); - } } + } else { + // todo: + // - groupB-ConfiguredTwoStepRA + // - msgA-DeltaPreamble + LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__); + } + /* Msg3 has not been transmitted yet */ + if (ra->first_Msg3) { + if (noGroupB) { + // use Group A preamble + prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); + ra->RA_usedGroupA = 1; + } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) { + // Group B is configured and RA preamble Group A is used + // - todo add condition on CCCH_sdu_size for initiation by CCCH + prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); + ra->RA_usedGroupA = 1; + } else { + // Group B preamble is configured and used + // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A + // the remaining belong to RA Preambles Group B + prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); + ra->RA_usedGroupA = 0; + } + } else { // Msg3 is being retransmitted + if (ra->RA_usedGroupA && noGroupB) { + prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb); + } else if (ra->RA_usedGroupA && !noGroupB){ + prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA); + } else { + prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); + } + } +} + +// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) +// - this does not apply to contention-free RA Preamble for beam failure recovery request +// - getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario) +// - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier +// - f_id: index of the PRACH occasion in the frequency domain +// - s_id is starting symbol of the PRACH occasion [0...14] +// - t_id is the first slot of the PRACH occasion in a system frame [0...80] +uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu){ + + RA_config_t *ra = &mac->ra; + uint8_t ul_carrier_id = 0; // NUL + uint8_t f_id = prach_pdu->num_ra; + uint8_t t_id = prach_pdu->prach_slot; + uint8_t s_id = prach_pdu->prach_start_symbol; + + ra->ra_rnti = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; + + LOG_D(MAC, "Computed ra_RNTI is %x \n", ra->ra_rnti); + + return ra->ra_rnti; + +} + +// This routine implements Section 5.1.2 (UE Random Access Resource Selection) +// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321 +// - currently the PRACH preamble is set through RRC configuration for 4-step CFRA mode +// todo: +// - determine next available PRACH occasion +// -- if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured +// -- else if SSB is selected above +// -- else if CSI-RS is selected above +// - switch initialisation cases +// -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) +// --- SSB selection, set prach_resources->ra_PreambleIndex +// -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 +// --- set PREAMBLE_INDEX to ra_preamble_index +// --- select the SSB signalled by PDCCH +// -- RA initiated for SI request: +// --- SSB selection, set prach_resources->ra_PreambleIndex +// - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) +// - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission +// - Contention-based RA preamble selection: +// -- selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB +void nr_get_prach_resources(module_id_t mod_id, + int CC_id, + uint8_t gNB_id, + NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, + NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + + LOG_D(PHY, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3); + + if (rach_ConfigDedicated) { + if (rach_ConfigDedicated->cfra){ + uint8_t cfra_ssb_resource_idx = 0; + prach_resources->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex; + LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, prach_resources->ra_PreambleIndex, cfra_ssb_resource_idx); + } + } else { + int16_t dl_pathloss = get_nr_PL(mod_id, CC_id, gNB_id); + ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu); + ra_preambles_config(prach_resources, mac, dl_pathloss); LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex); } - // todo determine next available PRACH occasion - // - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured - // - else if SSB is selected above - // - else if CSI-RS is selected above - - ///////////////////////////////////////////////////////////////////////////// - //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *////////// - ///////////////////////////////////////////////////////////////////////////// - // todo: - // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) - // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission - // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded) - - if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) - mac->RA_PREAMBLE_POWER_RAMPING_COUNTER++; - + if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) + prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++; prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); + prach_resources->ra_RNTI = set_ra_rnti(mac, prach_pdu); - // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) - // 1) this does not apply to contention-free RA Preamble for beam failure recovery request - // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario) - - prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex; - - // ra_RNTI computation - // - todo: this is for TDD FR1 only - // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier - // - f_id: index of the PRACH occasion in the frequency domain - // - s_id is starting symbol of the PRACH occasion [0...14] - // - t_id is the first slot of the PRACH occasion in a system frame [0...80] - - ul_carrier_id = 0; // NUL - f_id = rach_ConfigGeneric->msg1_FrequencyStart; - SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]; - s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; - - // Pick the first slot of the PRACH occasion in a system frame - for (i = 0; i < 10; i++){ - if (((SFN_nbr & (1 << i)) >> i) == 1){ - t_id = 2*i; - break; - } - } - prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; - mac->ra_rnti = prach_resources->ra_RNTI; - - LOG_D(MAC, "Computed ra_RNTI is %x \n", prach_resources->ra_RNTI); } // TbD: RA_attempt_number not used void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ - AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - mac->ra_state = WAIT_RAR; - // Start contention resolution timer - mac->RA_attempt_number++; + RA_config_t *ra = &mac->ra; + ra->ra_state = WAIT_RAR; + ra->RA_attempt_number++; } void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ - AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); - LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP); + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + RA_config_t *ra = &mac->ra; + + LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP); + // start contention resolution timer - mac->RA_contention_resolution_cnt = 0; - mac->RA_contention_resolution_timer_active = 1; + ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8; + ra->RA_contention_resolution_timer_active = 1; + } ///////////////////////////////////////////////////////////////////////// -///////* Random Access Preamble Initialization (5.1.1 TS 38.321) */////// +// This function handles: +// - Random Access Preamble Initialization (5.1.1 TS 38.321) +// - Random Access Response reception (5.1.4 TS 38.321) +/// In the current implementation, RA is 4-step contention free only ///////////////////////////////////////////////////////////////////////// -/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300) -/// Only one RA procedure is ongoing at any point in time in a MAC entity -/// the RA procedure on a SCell shall only be initiated by PDCCH order -/// in the current implementation, RA is contention free only - -// WIP // todo TS 38.321: -// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX // - BWP operation (subclause 5.15 TS 38.321) -// - handle initialization by beam failure recovery +// - beam failure recovery // - handle initialization by handover -// - handle transmission on DCCH using PRACH (during handover, or sending SR for example) +// - handle DL assignment on PDCCH for RA-RNTI +// - transmission on DCCH using PRACH (during handover, or sending SR for example) // - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader) // - fix rrc data req logic // - retrieve TBS // - add mac_rrc_nr_data_req_ue, etc ... -// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) - +// - Msg3 Retransmissions to be scheduled by DCI 0_0 uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + fapi_nr_ul_config_prach_pdu *prach_pdu, module_id_t mod_id, int CC_id, - UE_MODE_t UE_mode, frame_t frame, uint8_t gNB_id, - int nr_tti_tx){ + int nr_slot_tx){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload; - //uint8_t ra_ResponseWindow; uint16_t size_sdu = 0; unsigned short post_padding; - //fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; NR_ServingCellConfigCommon_t *scc = mac->scc; + AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "In %s: FATAL! nr_rach_ConfigCommon is NULL...\n", __FUNCTION__); NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__); NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; - //NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = mac->rach_ConfigDedicated; - - // int32_t frame_diff = 0; + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated; uint8_t sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int TBS_bytes = 848, header_length_total=0, num_sdus, offset, preambleTransMax, mac_ce_len; + int TBS_bytes = 848, header_length_total=0, num_sdus, offset, mac_ce_len; - AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); + // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side + if (!prach_resources->init_msg1) { + if (((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150){ + prach_resources->init_msg1 = 1; + } else { + return 0; + } + } - if (UE_mode < PUSCH && prach_resources->init_msg1) { + if (prach_resources->init_msg1) { - LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active); - - AssertFatal(setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); - - if (mac->RA_active == 0) { + if (ra->RA_active == 0) { /* RA not active - checking if RRC is ready to initiate the RA procedure */ - LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n"); - - mac->RA_RAPID_found = 0; - - /* Set RA_PREAMBLE_POWER_RAMPING_STEP */ - switch (rach_ConfigGeneric->powerRampingStep){ // in dB - case 0: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0; - break; - case 1: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2; - break; - case 2: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4; - break; - case 3: - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6; - break; - } - - prach_resources->RA_PREAMBLE_BACKOFF = 0; - prach_resources->RA_SCALING_FACTOR_BI = 1; - prach_resources->RA_PCMAX = 0; // currently hardcoded to 0 + LOG_D(MAC, "RA not active. Checking for data to transmit from upper layers...\n"); payload = (uint8_t*) &mac->CCCH_pdu.payload; - mac_ce_len = 0; num_sdus = 1; post_padding = 1; @@ -427,29 +562,19 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, size_sdu += sdu_lengths[0]; } - //mac->RA_tx_frame = frame; - //mac->RA_tx_subframe = nr_tti_tx; - //mac->RA_backoff_frame = frame; - //mac->RA_backoff_subframe = nr_tti_tx; - if (size_sdu > 0) { - LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame); + LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx); - mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; - mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); - mac->RA_prachMaskIndex = 0; - // todo: add the backoff condition here - mac->RA_backoff_cnt = 0; - mac->RA_active = 1; + ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); + + init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); prach_resources->Msg3 = payload; - nr_get_RA_window(mac); // Fill in preamble and PRACH resources - if (mac->generate_nr_prach == 1) - nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated); + if (ra->generate_nr_prach == 1) + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer (uint8_t *) payload, // UL MAC pdu pointer @@ -470,140 +595,61 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, payload[offset + j] = 0; // mac_pdu[offset + j] = 0; } } - } else if (mac->RA_window_cnt != -1) { // RACH is active + } else if (ra->RA_window_cnt != -1) { // RACH is active - //////////////////////////////////////////////////////////////// - /////* Random Access Response reception (5.1.4 TS 38.321) *///// - //////////////////////////////////////////////////////////////// - // Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER - // and RA_backoff_cnt - // todo: - // - handle beam failure recovery request - // - handle DL assignment on PDCCH for RA-RNTI - // - handle backoff and raResponseWindow params + LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt); - // LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n", - // mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe); - - if (mac->RA_BI_found){ - prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator; + if (ra->RA_BI_found){ + prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * ra->RA_backoff_indicator; } else { prach_resources->RA_PREAMBLE_BACKOFF = 0; } - if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) { - + if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) { // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213) - // TbD Msg3 Retransmissions to be scheduled by DCI 0_0 - mac->RA_active = 0; - mac->RA_window_cnt = -1; - mac->ra_state = RA_SUCCEEDED; - mac->generate_nr_prach = 2; - LOG_I(MAC, "[MAC][UE %d][RAPROC]: RAR successfully received \n", mod_id); - } else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) { + nr_ra_succeeded(mod_id, frame, nr_slot_tx); - LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception failed \n", mod_id, frame, nr_tti_tx); + } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) { - mac->ra_state = RA_UE_IDLE; - mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; + LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx); - preambleTransMax = -1; - switch (rach_ConfigGeneric->preambleTransMax) { - case 0: - preambleTransMax = 3; - break; - case 1: - preambleTransMax = 4; - break; - case 2: - preambleTransMax = 5; - break; - case 3: - preambleTransMax = 6; - break; - case 4: - preambleTransMax = 7; - break; - case 5: - preambleTransMax = 8; - break; - case 6: - preambleTransMax = 10; - break; - case 7: - preambleTransMax = 20; - break; - case 8: - preambleTransMax = 50; - break; - case 9: - preambleTransMax = 100; - break; - case 10: - preambleTransMax = 200; - break; - } + nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx); - // Resetting RA window - nr_get_RA_window(mac); + } else if (ra->RA_window_cnt > 0) { - if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){ - LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax); - mac->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1); - mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; - prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1; // 2 dB increment - prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); - } - - // compute backoff parameters - // if (mac->RA_backoff_cnt > 0){ - // frame_diff = (sframe_t) frame - mac->RA_backoff_frame; - // if (frame_diff < 0) frame_diff = -frame_diff; - // mac->RA_backoff_frame = frame; - // mac->RA_backoff_subframe = nr_tti_tx; - // } - // compute RA window parameters - // if (mac->RA_window_cnt > 0){ - // frame_diff = (frame_t) frame - mac->RA_tx_frame; - // if (frame_diff < 0) frame_diff = -frame_diff; - // mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->RA_tx_subframe)); - // LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, mac->RA_window_cnt); - // } - - // mac->RA_tx_frame = frame; - // mac->RA_tx_subframe = nr_tti_tx; + LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA window count %d) \n", mod_id, frame, nr_slot_tx, ra->RA_window_cnt); // Fill in preamble and PRACH resources - if (mac->generate_nr_prach == 1) - nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated); + ra->RA_window_cnt--; + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); - } else { + } else if (ra->RA_backoff_cnt > 0) { - mac->RA_window_cnt--; + LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA backoff count %d) \n", mod_id, frame, nr_slot_tx, ra->RA_backoff_cnt); - LOG_D(MAC, "[MAC][UE %d][RAPROC][%d.%d]: RAR not received yet (RA window count %d) \n", - mod_id, - frame, - nr_tti_tx, - mac->RA_window_cnt); + ra->RA_backoff_cnt--; - // Fill in preamble and PRACH resources - if (mac->generate_nr_prach == 1) - nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated); + if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == 1) || ra->RA_backoff_cnt == 0){ + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + } } } - } else if (UE_mode == PUSCH) { - LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id); - AssertFatal(1 == 0, ""); } - return mac->generate_nr_prach; + + if (ra->RA_contention_resolution_timer_active){ + nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources); + } + + return ra->generate_nr_prach; + } void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ uint8_t mu, ra_ResponseWindow; + RA_config_t *ra = &mac->ra; NR_ServingCellConfigCommon_t *scc = mac->scc; NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; @@ -616,32 +662,139 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ else mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - mac->RA_window_cnt = mac->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB + ra->RA_window_cnt = ra->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB switch (ra_ResponseWindow) { case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: - mac->RA_window_cnt += 1; + ra->RA_window_cnt += 1; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2: - mac->RA_window_cnt += 2; + ra->RA_window_cnt += 2; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4: - mac->RA_window_cnt += 4; + ra->RA_window_cnt += 4; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8: - mac->RA_window_cnt += 8; + ra->RA_window_cnt += 8; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10: - mac->RA_window_cnt += 10; + ra->RA_window_cnt += 10; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20: - mac->RA_window_cnt += 20; + ra->RA_window_cnt += 20; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40: - mac->RA_window_cnt += 40; + ra->RA_window_cnt += 40; break; case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80: - mac->RA_window_cnt += 80; + ra->RA_window_cnt += 80; break; } } + +//////////////////////////////////////////////////////////////////////////// +/////////* Random Access Contention Resolution (5.1.35 TS 38.321) *///////// +//////////////////////////////////////////////////////////////////////////// +// Handling contention resolution timer +// WIP todo: +// - beam failure recovery +// - RA completed +void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + RA_config_t *ra = &mac->ra; + + if (ra->RA_contention_resolution_timer_active == 1) { + + ra->RA_contention_resolution_cnt--; + + LOG_D(MAC, "In %s: [%d.%d] RA contention resolution timer %d\n", __FUNCTION__, frame, slot, ra->RA_contention_resolution_cnt); + + if (ra->RA_contention_resolution_cnt == 0) { + ra->t_crnti = 0; + ra->RA_active = 0; + ra->RA_contention_resolution_timer_active = 0; + // Signal PHY to quit RA procedure + LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id); + nr_ra_failed(module_id, cc_id, prach_resources, frame, slot); + } + + } +} + +// Handlig successful RA completion @ MAC layer +// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16 +// todo: +// - complete handling of received contention-based RA preamble +void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + + if (ra->cfra) { + + LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot); + + ra->RA_window_cnt = -1; + + } else { + + LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot); + + ra->RA_contention_resolution_cnt = -1; + ra->RA_contention_resolution_timer_active = 0; + ra->t_crnti = 0; + + LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot); + + } + + LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id); + ra->RA_active = 0; + ra->generate_nr_prach = 2; + ra->ra_state = RA_SUCCEEDED; + +} + +// Handlig failure of RA procedure @ MAC layer +// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16 +// todo: +// - complete handling of received contention-based RA preamble +// - 2-step RA implementation +void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) { + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + + ra->first_Msg3 = 0; + ra->generate_nr_prach = 3; + ra->ra_state = RA_UE_IDLE; + + prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++; + + if(prach_resources->RA_TYPE == RA_4STEP){ + + if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1){ + + LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", __FUNCTION__, mod_id, frame, slot, ra->preambleTransMax); + + ra->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1); + + prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); + + } else { + + // Resetting RA window + nr_get_RA_window(mac); + + } + + } else if (prach_resources->RA_TYPE == RA_2STEP){ + + LOG_E(MAC, "Missing implementation of RA failure handling for 2-step RA...\n"); + + } + +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 33aed06aec..11edc6c20d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -38,6 +38,7 @@ #include "common/utils/nr/nr_common.h" #include "executables/softmodem-common.h" #include +#include "nfapi_nr_interface.h" #ifdef NR_PDCCH_DCI_TOOLS_DEBUG #define LOG_DCI_D(a...) printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) ->" a) @@ -53,32 +54,45 @@ dci_pdu_rel15_t *def_dci_pdu_rel15; 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=3; - rel15->CCE[0]=0; - rel15->L[0]=4; - rel15->CCE[1]=4; - rel15->L[1]=4; - rel15->CCE[2]=8; - rel15->L[2]=4; + uint8_t aggregation; + find_aggregation_candidates(&aggregation, + &rel15->number_of_candidates, + ss); + + for (int i=0; inumber_of_candidates; i++) { + rel15->CCE[i] = i*aggregation; + rel15->L[i] = aggregation; + } } void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id){ + RA_config_t *ra = &mac->ra; uint16_t monitoringSymbolsWithinSlot = 0; - uint8_t bwp_id = 1, coreset_id = 1; + uint8_t coreset_id = 1; int sps = 0; - def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t)); + def_dci_pdu_rel15 = calloc(1,2*sizeof(dci_pdu_rel15_t)); AssertFatal(mac->scc != NULL, "scc is null\n"); + NR_BWP_Id_t bwp_id = mac->DL_BWP_Id; NR_ServingCellConfigCommon_t *scc = mac->scc; NR_BWP_DownlinkCommon_t *bwp_Common = mac->DLbwp[bwp_id - 1]->bwp_Common; NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP; - NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id]; - // CORESET configuration - NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id - 1]; + NR_SearchSpace_t *ss; + NR_ControlResourceSet_t *coreset; + if(ss_id>=0) { + ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id]; + coreset = mac->coreset[bwp_id - 1][coreset_id - 1]; + rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; + } else { + ss = mac->search_space_zero; + coreset = mac->coreset0; + rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + } + rel15->coreset.duration = coreset->duration; + for (int i = 0; i < 6; i++) rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i]; rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; @@ -93,13 +107,13 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->coreset.InterleaverSize = 0; rel15->coreset.ShiftIndex = 0; } - rel15->coreset.CoreSetType = 1; + rel15->coreset.precoder_granularity = coreset->precoderGranularity; // Scrambling RNTI if (coreset->pdcch_DMRS_ScramblingID) { rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID; - rel15->coreset.scrambling_rnti = mac->t_crnti; + rel15->coreset.scrambling_rnti = mac->crnti; } else { rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId; rel15->coreset.scrambling_rnti = 0; @@ -117,20 +131,20 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t // for SPS=14 8 MSBs in positions 13 down to 6 monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); rel15->rnti = mac->crnti; - rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275); - rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); + rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing; for (int i = 0; i < rel15->num_dci_options; i++) { - rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id); + rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15+i, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id); } break; case NR_RNTI_RA: // we use the initial DL BWP sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - rel15->rnti = mac->ra_rnti; - rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); - rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + rel15->rnti = ra->ra_rnti; + rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id); break; @@ -143,6 +157,20 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t case NR_RNTI_SP_CSI: break; case NR_RNTI_SI: + // we use DL BWP dedicated + sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + + // for SPS=14 8 MSBs in positions 13 down to 6 + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + + rel15->rnti = SI_RNTI; // SI-RNTI - 3GPP TS 38.321 Table 7.1-1: RNTI values + rel15->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs; + rel15->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb; + rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; + + for (int i = 0; i < rel15->num_dci_options; i++) { + rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0); + } break; case NR_RNTI_SFI: break; @@ -169,8 +197,8 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t rel15->BWPSize, rel15->BWPStart, rel15->SubcarrierSpacing, - rel15->dci_format, - rel15->dci_length, + rel15->dci_format_options[0], + rel15->dci_length_options[0], sps, monitoringSymbolsWithinSlot); #endif @@ -181,12 +209,14 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) { + RA_config_t *ra = &mac->ra; int ss_id; uint8_t bwp_id = 1, coreset_id = 1; + //NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; NR_BWP_Downlink_t *bwp = mac->DLbwp[bwp_id - 1]; #ifdef DEBUG_DCI - LOG_D(MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &mac->ra_rnti, mac->ra_rnti, &mac->crnti, mac->crnti, &mac->t_crnti, mac->t_crnti); + LOG_D(MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &ra->ra_rnti, ra->ra_rnti, &mac->crnti, mac->crnti, &ra->t_crnti, ra->t_crnti); #endif // loop over all available SS for BWP ID 1, CORESET ID 1 @@ -203,23 +233,26 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl // Fetch configuration for searchSpaceZero // note: The search space with the SearchSpaceId = 0 identifies the search space configured via PBCH (MIB) and in ServingCellConfigCommon (searchSpaceZero). if (pdcch_ConfigCommon->choice.setup->searchSpaceZero){ + if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 == NULL){ + pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*pdcch_ConfigCommon->choice.setup->searchSpaceSIB1)); + } + *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = 0; LOG_D(MAC, "[DCI_CONFIG] Configure SearchSpace#0 of the initial BWP\n"); - LOG_W(MAC, "[DCI_CONFIG] This should not be available yet..."); } if (ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0){ // check available SS IDs if (pdcch_ConfigCommon->choice.setup->ra_SearchSpace){ if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){ - LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n"); - switch(mac->ra_state){ + switch(ra->ra_state){ case WAIT_RAR: + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n"); rel15->num_dci_options = 1; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id); fill_dci_search_candidates(ss, rel15); break; case WAIT_CONTENTION_RESOLUTION: - rel15->rnti = mac->t_crnti; + LOG_E(MAC, "In %s: CB-RA not implemented yet. Should not have fallen in this case.\n", __FUNCTION__); break; default: break; @@ -284,7 +317,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl if (ss->searchSpaceType->choice.ue_Specific){ if(ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1){ // Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI - if (get_softmodem_params()->phy_test == 1 && mac->crnti > 0) { + if ((ra->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) && mac->crnti > 0) { LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n"); rel15->num_dci_options = 2; rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_1; @@ -324,4 +357,25 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl break; } } + + // Search space 0, CORESET ID 0 + + NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common; + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; + + if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){ + + NR_SearchSpace_t *ss0 = mac->search_space_zero; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + + if (ss0->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){ + if( (frame%2 == mac->type0_PDCCH_CSS_config.sfn_c) && (slot == mac->type0_PDCCH_CSS_config.n_0) ){ + rel15->num_dci_options = 1; + rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0; + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_SI, -1); + fill_dci_search_candidates(ss0, rel15); + } + } + } + } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index e237a910c6..64067e9d60 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -45,233 +45,52 @@ #include "NR_PDCCH-ConfigCommon.h" /* MAC */ -#include "mac_defs.h" #include "NR_MAC_COMMON/nr_mac.h" #include "NR_MAC_UE/mac_proto.h" #include "NR_MAC_UE/mac_extern.h" +#include "NR_MAC_COMMON/nr_mac_extern.h" #include "common/utils/nr/nr_common.h" /* PHY */ -#include "SCHED_NR_UE/defs.h" -#include "PHY/defs_nr_UE.h" #include "PHY/NR_TRANSPORT/nr_dci.h" - -/*Openair Packet Tracer */ -#include "UTIL/OPT/opt.h" -#include "OCG.h" #include "executables/softmodem-common.h" +#include "SCHED_NR_UE/defs.h" /* utils */ #include "assertions.h" - +#include "asn1_conversions.h" #include "common/utils/LOG/log.h" -#include "SIMULATION/TOOLS/sim.h" // for taus -#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #include "common/utils/LOG/vcd_signal_dumper.h" -#include -#include - //#define ENABLE_MAC_PAYLOAD_DEBUG 1 -#define DEBUG_EXTRACT_DCI 1 +//#define DEBUG_EXTRACT_DCI +//#define DEBUG_RAR -extern int bwp_id; -extern dci_pdu_rel15_t *def_dci_pdu_rel15; -extern const uint16_t nr_slots_per_frame[5]; +int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){ -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); + RA_config_t *ra = &mac->ra; + int rnti_type; -void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, - fapi_nr_dl_config_request_t *dl_config, - fapi_nr_ul_config_request_t *ul_config, - fapi_nr_tx_request_t *tx_request, - module_id_t mod_id, - int cc_id, - frame_t frame, - int slot){ - - scheduled_response->dl_config = dl_config; - scheduled_response->ul_config = ul_config; - scheduled_response->tx_request = tx_request; - scheduled_response->module_id = mod_id; - scheduled_response->CC_id = cc_id; - scheduled_response->frame = frame; - scheduled_response->slot = slot; - -} - -uint32_t get_ssb_slot(uint32_t ssb_index){ - // this function now only support f <= 3GHz - return ssb_index & 0x3 ; - - // return first_symbol(case, freq, ssb_index) / 14 -} - -uint8_t table_9_2_2_1[16][8]={ - {0,12,2, 0, 0,3,0,0}, - {0,12,2, 0, 0,4,8,0}, - {0,12,2, 3, 0,4,8,0}, - {1,10,4, 0, 0,6,0,0}, - {1,10,4, 0, 0,3,6,9}, - {1,10,4, 2, 0,3,6,9}, - {1,10,4, 4, 0,3,6,9}, - {1,4, 10,0, 0,6,0,0}, - {1,4, 10,0, 0,3,6,9}, - {1,4, 10,2, 0,3,6,9}, - {1,4, 10,4, 0,3,6,9}, - {1,0, 14,0, 0,6,0,0}, - {1,0, 14,0, 0,3,6,9}, - {1,0, 14,2, 0,3,6,9}, - {1,0, 14,4, 0,3,6,9}, - {1,0, 14,26,0,3,0,0} -}; - -#if 0 // Not in use. In case of use, please adapt the schedule_response (no longer in MAC) -int8_t nr_ue_process_dlsch(module_id_t module_id, - int cc_id, - uint8_t gNB_index, - fapi_nr_dci_indication_t *dci_ind, - void *pduP, - uint32_t pdu_len) -{ - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; - //fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - nr_phy_config_t *phy_config = &mac->phy_config; - - //ul_config->ul_config_list[ul_config->number_pdus].pusch_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!=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 (rnti == ra->ra_rnti) { + rnti_type = NR_RNTI_RA; + } else if (rnti == mac->crnti) { + rnti_type = NR_RNTI_C; + } else if (rnti == ra->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; + } else { + AssertFatal(1 == 0, "In %s: Not identified/handled rnti %d \n", __FUNCTION__, rnti); } - } - 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 - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.bandwidth_part_ind = 0; //FIXME - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rb_size = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rb_start = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.nr_of_symbols = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.start_symbol_index = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.frequency_hopping = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.mcs_index = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.pusch_data.new_data_indicator = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.pusch_data.rv_index = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.pusch_data.harq_process_id = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.absolute_delta_PUSCH = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.nrOfLayers = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.transform_precoding = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.dmrs_ports = 0; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.dmrs_config_type = 0; - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.n_front_load_symb = 0; //FIXME - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.srs_config = 0; //FIXME - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.csi_reportTriggerSize = 0; //FIXME - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.maxCodeBlockGroupsPerTransportBlock = 0; //FIXME - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.ptrs_dmrs_association_port = 0; FIXME - //ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.beta_offset_ind = 0; //FIXME - } 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.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; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.additionalDMRS = 0; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.maxCodeRate = 0; - 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.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_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 */ - 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; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.additionalDMRS = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format1.additional_dmrs; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.maxCodeRate = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format1.max_code_rate; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSlots = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format1.number_of_slots; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pi2PBSK = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format1.pi2bpsk; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.simultaneousHARQ_ACK_CSI = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format1.simultaneous_harq_ack_csi; - break; - case pucch_format2_nr: - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.interslotFrequencyHopping = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format2.inter_slot_frequency_hopping; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.additionalDMRS = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format2.additional_dmrs; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.maxCodeRate = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format2.max_code_rate; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSlots = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format2.number_of_slots; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pi2PBSK = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format2.pi2bpsk; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.simultaneousHARQ_ACK_CSI = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format2.simultaneous_harq_ack_csi; - break; - case pucch_format3_nr: - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.interslotFrequencyHopping = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format3.inter_slot_frequency_hopping; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.additionalDMRS = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format3.additional_dmrs; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.maxCodeRate = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format3.max_code_rate; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSlots = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format3.number_of_slots; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pi2PBSK = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format3.pi2bpsk; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.simultaneousHARQ_ACK_CSI = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format3.simultaneous_harq_ack_csi; - break; - case pucch_format4_nr: - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.interslotFrequencyHopping = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format4.inter_slot_frequency_hopping; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.additionalDMRS = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format4.additional_dmrs; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.maxCodeRate = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format4.max_code_rate; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.nrofSlots = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format4.number_of_slots; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.pi2PBSK = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format4.pi2bpsk; - ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu.simultaneousHARQ_ACK_CSI = phy_config->config_req.ul_bwp_dedicated.pucch_config_dedicated.format4.simultaneous_harq_ack_csi; - break; - 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.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.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_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); - } - return 0; + LOG_D(MAC, "In %s: returning rnti_type %s \n", __FUNCTION__, rnti_types[rnti_type]); + + return rnti_type; + } -#endif + int8_t nr_ue_decode_mib(module_id_t module_id, int cc_id, @@ -294,1899 +113,67 @@ int8_t nr_ue_decode_mib(module_id_t module_id, uint16_t frame_number_4lsb = 0; for (int i=0; i<4; i++) frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i); - //uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4] + uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4] uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5] uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset; - //uint32_t ssb_index = 0; // TODO: ssb_index should obtain from L1 in case Lssb != 64 - frame = frame << 4; frame = frame | frame_number_4lsb; - if(ssb_length == 64){ - ssb_index = ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] } + for (int i=0; i<3; i++) + ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i)); }else{ if(ssb_subcarrier_offset_msb){ ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10; } } -#ifdef DEBUG_MIB - LOG_I(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]); - LOG_I(MAC,"system frame number(with LSB): %d\n", (int)frame); - LOG_I(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon); - LOG_I(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset); - LOG_I(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position); - LOG_I(MAC,"pdcch config sib1: %d\n", (int)mac->mib->pdcch_ConfigSIB1); - LOG_I(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred); - LOG_I(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection); - LOG_I(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit); - LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index); -#endif + LOG_D(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]); + LOG_D(MAC,"system frame number(with LSB): %d\n", (int)frame); + LOG_D(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon); + LOG_D(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset); + LOG_D(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position); + LOG_D(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred); + LOG_D(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection); + LOG_D(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit); + LOG_D(MAC,"ssb index(extra bits): %d\n", (int)ssb_index); - subcarrier_spacing_t scs_ssb = scs_30kHz; // default for - //const uint32_t scs_index = 0; - const uint32_t num_slot_per_frame = 20; - subcarrier_spacing_t scs_pdcch; + //storing ssb index in the mac structure + mac->mib_ssb = ssb_index; - // assume carrier frequency < 6GHz - if(mac->mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){ - scs_pdcch = scs_15kHz; - }else{ //NR_MIB__subCarrierSpacingCommon_scs30or120 - scs_pdcch = scs_30kHz; - } + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index, + mac->phy_config.config_req.ssb_table.ssb_offset_point_a); - 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; - uint32_t index_4msb = (mac->mib->pdcch_ConfigSIB1.controlResourceSetZero); - uint32_t index_4lsb = (mac->mib->pdcch_ConfigSIB1.searchSpaceZero); - int32_t num_rbs = -1; - int32_t num_symbols = -1; - int32_t rb_offset = -1; - //LOG_I(MAC,"<<<<<<<<mib->pdcch_ConfigSIB1,index_4msb,index_4lsb,scs_ssb,scs_pdcch, (scs_ssb << 5)|scs_pdcch); + ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; // TODO: ssb_index should obtain from L1 in case Lssb != 64 + mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern; + mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c; + mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c; + mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame; + mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS - // type0-pdcch coreset - switch( (scs_ssb << 5)|scs_pdcch ){ - case (scs_15kHz << 5) | scs_15kHz : - AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n"); - mac->type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_1_c2[index_4msb]; - num_symbols = table_38213_13_1_c3[index_4msb]; - rb_offset = table_38213_13_1_c4[index_4msb]; - break; - - case (scs_15kHz << 5) | scs_30kHz: - AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n"); - mac->type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_2_c2[index_4msb]; - num_symbols = table_38213_13_2_c3[index_4msb]; - rb_offset = table_38213_13_2_c4[index_4msb]; - break; - - case (scs_30kHz << 5) | scs_15kHz: - if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ - AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n"); - mac->type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_3_c2[index_4msb]; - num_symbols = table_38213_13_3_c3[index_4msb]; - rb_offset = table_38213_13_3_c4[index_4msb]; - }else if(min_channel_bw & bw_40MHz){ - AssertFatal(index_4msb < 9, "38.213 Table 13-5 4 MSB out of range\n"); - mac->type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_5_c2[index_4msb]; - num_symbols = table_38213_13_5_c3[index_4msb]; - rb_offset = table_38213_13_5_c4[index_4msb]; - }else{ ; } - - break; - - case (scs_30kHz << 5) | scs_30kHz: - if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){ - mac->type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_4_c2[index_4msb]; - num_symbols = table_38213_13_4_c3[index_4msb]; - rb_offset = table_38213_13_4_c4[index_4msb]; - LOG_I(MAC,"<<<<<<<<type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_6_c2[index_4msb]; - num_symbols = table_38213_13_6_c3[index_4msb]; - rb_offset = table_38213_13_6_c4[index_4msb]; - }else{ ; } - break; - - case (scs_120kHz << 5) | scs_60kHz: - AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n"); - if(index_4msb & 0x7){ - mac->type0_pdcch_ss_mux_pattern = 1; - }else if(index_4msb & 0x18){ - mac->type0_pdcch_ss_mux_pattern = 2; - }else{ ; } - - num_rbs = table_38213_13_7_c2[index_4msb]; - num_symbols = table_38213_13_7_c3[index_4msb]; - if(!is_condition_A && (index_4msb == 8 || index_4msb == 10)){ - rb_offset = table_38213_13_7_c4[index_4msb] - 1; - }else{ - rb_offset = table_38213_13_7_c4[index_4msb]; - } - break; - - case (scs_120kHz << 5) | scs_120kHz: - AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n"); - if(index_4msb & 0x3){ - mac->type0_pdcch_ss_mux_pattern = 1; - }else if(index_4msb & 0x0c){ - mac->type0_pdcch_ss_mux_pattern = 3; - } - - num_rbs = table_38213_13_8_c2[index_4msb]; - num_symbols = table_38213_13_8_c3[index_4msb]; - if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){ - rb_offset = table_38213_13_8_c4[index_4msb] - 1; - }else{ - rb_offset = table_38213_13_8_c4[index_4msb]; - } - break; - - case (scs_240kHz << 5) | scs_60kHz: - AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n"); - mac->type0_pdcch_ss_mux_pattern = 1; - num_rbs = table_38213_13_9_c2[index_4msb]; - num_symbols = table_38213_13_9_c3[index_4msb]; - rb_offset = table_38213_13_9_c4[index_4msb]; - break; - - case (scs_240kHz << 5) | scs_120kHz: - AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n"); - if(index_4msb & 0x3){ - mac->type0_pdcch_ss_mux_pattern = 1; - }else if(index_4msb & 0x0c){ - mac->type0_pdcch_ss_mux_pattern = 2; - } - num_rbs = table_38213_13_10_c2[index_4msb]; - num_symbols = table_38213_13_10_c3[index_4msb]; - if(!is_condition_A && (index_4msb == 4 || index_4msb == 6)){ - rb_offset = table_38213_13_10_c4[index_4msb]-1; - }else{ - rb_offset = table_38213_13_10_c4[index_4msb]; - } - - break; - - default: - break; - } - - AssertFatal(num_rbs != -1, "Type0 PDCCH coreset num_rbs undefined"); - AssertFatal(num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined"); - AssertFatal(rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined"); - - //uint32_t cell_id = 0; // obtain from L1 later - - //mac->type0_pdcch_dci_config.coreset.rb_start = rb_offset; - //mac->type0_pdcch_dci_config.coreset.rb_end = rb_offset + num_rbs - 1; - uint64_t mask = 0x0; - uint8_t i; - for(i=0; i<(num_rbs/6); ++i){ // 38.331 Each bit corresponds a group of 6 RBs - mask = mask >> 1; - 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; - */ - - - // type0-pdcch search space - float big_o; - float big_m; - uint32_t temp; - 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 - // 38.213 table 10.1-1 - - /// MUX PATTERN 1 - if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){ - big_o = table_38213_13_11_c1[index_4lsb]; - number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; - big_m = table_38213_13_11_c3[index_4lsb]; - - temp = (uint32_t)(big_o*pow(2, scs_pdcch)) + (uint32_t)(ssb_index*big_m); - n_c = temp / num_slot_per_frame; - if((temp/num_slot_per_frame) & 0x1){ - sfn_c = SFN_C_MOD_2_EQ_1; - }else{ - sfn_c = SFN_C_MOD_2_EQ_0; - } - - if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 7) && (ssb_index&1)){ - first_symbol_index = num_symbols; - }else{ - first_symbol_index = table_38213_13_11_c4[index_4lsb]; - } - // 38.213 chapter 13: over two consecutive slots - search_space_duration = 2; - } - - if(mac->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){ - big_o = table_38213_13_12_c1[index_4lsb]; - number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; - big_m = table_38213_13_12_c3[index_4lsb]; - - if((index_4lsb == 1 || index_4lsb == 3 || index_4lsb == 5 || index_4lsb == 10) && (ssb_index&1)){ - first_symbol_index = 7; - }else if((index_4lsb == 6 || index_4lsb == 7 || index_4lsb == 8 || index_4lsb == 11) && (ssb_index&1)){ - first_symbol_index = num_symbols; - }else{ - first_symbol_index = 0; - } - // 38.213 chapter 13: over two consecutive slots - search_space_duration = 2; - } - - /// MUX PATTERN 2 - if(mac->type0_pdcch_ss_mux_pattern == 2){ - - if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){ - // 38.213 Table 13-13 - AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n"); - // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot - // sfn_c = SFN_C_EQ_SFN_SSB; - n_c = get_ssb_slot(ssb_index); - switch(ssb_index & 0x3){ // ssb_index(i) mod 4 - case 0: - first_symbol_index = 0; - break; - case 1: - first_symbol_index = 1; - break; - case 2: - first_symbol_index = 6; - break; - case 3: - first_symbol_index = 7; - break; - default: break; - } - - }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ - // 38.213 Table 13-14 - AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n"); - // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot - // sfn_c = SFN_C_EQ_SFN_SSB; - n_c = get_ssb_slot(ssb_index); - switch(ssb_index & 0x7){ // ssb_index(i) mod 8 - case 0: - first_symbol_index = 0; - break; - case 1: - first_symbol_index = 1; - break; - case 2: - first_symbol_index = 2; - break; - case 3: - first_symbol_index = 3; - break; - case 4: - first_symbol_index = 12; - n_c = get_ssb_slot(ssb_index) - 1; - break; - case 5: - first_symbol_index = 13; - n_c = get_ssb_slot(ssb_index) - 1; - break; - case 6: - first_symbol_index = 0; - break; - case 7: - first_symbol_index = 1; - break; - default: break; - } - }else{ ; } - // 38.213 chapter 13: over one slot - search_space_duration = 1; - } - - /// MUX PATTERN 3 - if(mac->type0_pdcch_ss_mux_pattern == 3){ - if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){ - // 38.213 Table 13-15 - AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n"); - // PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot - // sfn_c = SFN_C_EQ_SFN_SSB; - n_c = get_ssb_slot(ssb_index); - switch(ssb_index & 0x3){ // ssb_index(i) mod 4 - case 0: - first_symbol_index = 4; - break; - case 1: - first_symbol_index = 8; - break; - case 2: - first_symbol_index = 2; - break; - case 3: - first_symbol_index = 6; - break; - default: break; - } - }else{ ; } - // 38.213 chapter 13: over one slot - search_space_duration = 1; - } - - AssertFatal(number_of_search_space_per_slot!=UINT_MAX,""); - /* - uint32_t 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 - 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.Mod_id = module_id; - mac->phy_config.CC_id = cc_id; - - mac->dl_config_request.sfn = frame; - mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS - - //} return 0; - } +int8_t nr_ue_decode_sib1(module_id_t module_id, + int cc_id, + unsigned int gNB_index, + uint32_t sibs_mask, + uint8_t *pduP, + uint32_t pdu_len) { + LOG_D(MAC, "Decode sib1\n"); + nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); + return 0; +} // TODO: change to UE parameter, scs: 15KHz, slot duration: 1ms uint32_t get_ssb_frame(uint32_t test){ return test; } -// Performs : -// 1. TODO: Call RRC for link status return to PHY -// 2. TODO: Perform SR/BSR procedures for scheduling feedback -// 3. TODO: Perform PHR procedures -NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info){ - - uint32_t search_space_mask = 0; - - if (dl_info){ - - module_id_t mod_id = dl_info->module_id; - uint32_t gNB_index = dl_info->gNB_index; - int cc_id = dl_info->cc_id; - frame_t rx_frame = dl_info->frame; - slot_t rx_slot = dl_info->slot; - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - nr_scheduled_response_t scheduled_response; - nr_dcireq_t dcireq; - - // check type0 from 38.213 13 if we have no CellGroupConfig - // TODO: implementation to be completed - if (mac->scg == NULL) { - if(dl_info->ssb_index != -1){ - - if(mac->type0_pdcch_ss_mux_pattern == 1){ - // 38.213 chapter 13 - if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; - } - if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; - } - } - if(mac->type0_pdcch_ss_mux_pattern == 2){ - // 38.213 Table 13-13, 13-14 - if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; - } - } - if(mac->type0_pdcch_ss_mux_pattern == 3){ - // 38.213 Table 13-15 - if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ - search_space_mask = search_space_mask | type0_pdcch; - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; - } - } - } // ssb_index != -1 - - // Type0 PDCCH search space - if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){ - mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1; - - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config; - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; - - /* - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set - - LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n", - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti, - dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP); - */ - dl_config->number_pdus = dl_config->number_pdus + 1; - - fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); - } - } else { // we have an scg - - dcireq.module_id = mod_id; - dcireq.gNB_index = gNB_index; - dcireq.cc_id = cc_id; - dcireq.frame = rx_frame; - dcireq.slot = rx_slot; - dcireq.dl_config_req.number_pdus = 0; - nr_ue_dcireq(&dcireq); //to be replaced with function pointer later - - fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - mac->if_module->scheduled_response(&scheduled_response); - } - - /* - if(search_space_mask & type0a_pdcch){ - } - - if(search_space_mask & type1_pdcch){ - } - - if(search_space_mask & type2_pdcch){ - } - - if(search_space_mask & type3_pdcch){ - } - */ - } - } else if (ul_info) { - - if (get_softmodem_params()->phy_test && ul_info->slot_tx == 8) { // ULSCH is handled only in phy-test mode (consistently with OAI gNB) - - uint8_t nb_dmrs_re_per_rb; - uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; - uint8_t data_existing = 0; - uint16_t TBS_bytes; - uint32_t TBS; - int i, N_PRB_oh; - - module_id_t mod_id = ul_info->module_id; - uint32_t gNB_index = ul_info->gNB_index; - int cc_id = ul_info->cc_id; - frame_t rx_frame = ul_info->frame_rx; - slot_t rx_slot = ul_info->slot_rx; - frame_t frame_tx = ul_info->frame_tx; - slot_t slot_tx = ul_info->slot_tx; - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - uint8_t access_mode = SCHEDULED_ACCESS; - - // program PUSCH with UL DCI parameters - nr_dcireq_t dcireq; - nr_scheduled_response_t scheduled_response; - fapi_nr_tx_request_t tx_req; - fapi_nr_tx_request_body_t tx_req_body; - fapi_nr_ul_config_request_t *ul_config = &dcireq.ul_config_req; - nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; - - fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &mac->ul_config_request.ul_config_list[0]; - - uint16_t rnti = ulcfg_pdu->pusch_config_pdu.rnti; - uint32_t rb_size = ulcfg_pdu->pusch_config_pdu.rb_size; - uint32_t rb_start = ulcfg_pdu->pusch_config_pdu.rb_start; - uint8_t nr_of_symbols = ulcfg_pdu->pusch_config_pdu.nr_of_symbols; - uint8_t start_symbol_index = ulcfg_pdu->pusch_config_pdu.start_symbol_index; - uint8_t nrOfLayers = 1; - uint8_t mcs_index = ulcfg_pdu->pusch_config_pdu.mcs_index; - uint8_t mcs_table = ulcfg_pdu->pusch_config_pdu.mcs_table; - uint8_t harq_process_id = ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id; - uint8_t rv_index = ulcfg_pdu->pusch_config_pdu.pusch_data.rv_index; - uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); - uint8_t dmrs_config_type = 0; - uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - // These should come from RRC config!!! - uint8_t ptrs_mcs1 = 2; - uint8_t ptrs_mcs2 = 4; - uint8_t ptrs_mcs3 = 10; - uint16_t n_rb0 = 25; - uint16_t n_rb1 = 75; - uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table); - uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size); - uint16_t number_dmrs_symbols = 0; - uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index; - -#ifdef DEBUG_DCI - LOG_I(MAC, " UL config params \n rnti: %x \n rb_size: %d \n", - rnti, rb_size); - LOG_I(MAC, "rb_start: %x \n nr_of_symbols: %d \n start_symbol_index: %d \n nrOfLayers: %d \n mcs_index: %d \n \ - mcs_table: %d \n harq_process_id: %d \n ndi: %d \n num_cb: %d \n rv_index: %d \n", - rb_start, nr_of_symbols, start_symbol_index, nrOfLayers, mcs_index, - mcs_table, harq_process_id, ndi, num_cb, rv_index); -#endif - - // PTRS ports configuration - // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised! - ptrs_ports_list.ptrs_re_offset = 0; - - // Num PRB Overhead from PUSCH-ServingCellConfig - if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL) - N_PRB_oh = 0; - else - N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead; - - ul_config->slot = ul_info->slot_tx; - ul_config->number_pdus = 1; - ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; - ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti; - ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size; - ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start; - ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols; - ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index; - ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos; - ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type; - ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index; - ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table; - ul_config->ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index; - ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id; - ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; - ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate = nr_get_code_rate_ul(mcs_index, mcs_table); - ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order = nr_get_Qm_ul(mcs_index, mcs_table); - - if (1 << ptrs_time_density >= nr_of_symbols) { - ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS - } - - get_num_re_dmrs(&ul_config->ul_config_list[0].pusch_config_pdu, - &nb_dmrs_re_per_rb, - &number_dmrs_symbols); - - TBS = nr_compute_tbs(ul_config->ul_config_list[0].pusch_config_pdu.qam_mod_order, - ul_config->ul_config_list[0].pusch_config_pdu.target_code_rate, - rb_size, - nr_of_symbols, - nb_dmrs_re_per_rb*number_dmrs_symbols, - N_PRB_oh, - 0, - nrOfLayers); - TBS_bytes = TBS/8; - ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS_bytes; - - if (IS_SOFTMODEM_NOS1){ - // Getting IP traffic to be transmitted - data_existing = nr_ue_get_sdu(mod_id, - cc_id, - frame_tx, - slot_tx, - 0, - ulsch_input_buffer, - TBS_bytes, - &access_mode); - } - - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - if (!IS_SOFTMODEM_NOS1 || !data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(PHY, "Random data to be tranmsitted: \n"); - - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = 0x31; - - for (i = 1; i < TBS_bytes; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); - //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - } - } - -#ifdef DEBUG_MAC_PDU - - LOG_D(PHY, "Is data existing ?: %d \n", data_existing); - LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes); - for (i = 0; i < TBS_bytes; i++) { - printf("%02x", ulsch_input_buffer[i]); - } - printf("\n"); - -#endif - - dcireq.module_id = mod_id; - dcireq.gNB_index = gNB_index; - dcireq.cc_id = cc_id; - dcireq.frame = rx_frame; - dcireq.slot = rx_slot; - - // Config UL TX PDU - tx_req.slot = slot_tx; - tx_req.sfn = frame_tx; - // tx_req->tx_config // TbD - tx_req.number_of_pdus = 1; - tx_req_body.pdu_length = TBS_bytes; - tx_req_body.pdu_index = 0; - tx_req_body.pdu = ulsch_input_buffer; - tx_req.tx_request_body = &tx_req_body; - - fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - mac->if_module->scheduled_response(&scheduled_response); - } - - // TODO: expand - // Note: Contention resolution is currently not active - if (mac->RA_contention_resolution_timer_active == 1) - ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx); - - } else if (get_softmodem_params()->do_ra){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id); - - if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){ - - uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; - nr_scheduled_response_t scheduled_response; - fapi_nr_tx_request_t tx_req; - fapi_nr_tx_request_body_t tx_req_body; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; - fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus]; - uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size; - - //if (IS_SOFTMODEM_NOS1){ - // // Getting IP traffic to be transmitted - // data_existing = nr_ue_get_sdu(mod_id, - // cc_id, - // frame_tx, - // slot_tx, - // 0, - // ulsch_input_buffer, - // TBS_bytes, - // &access_mode); - //} - - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - //if (!IS_SOFTMODEM_NOS1 || !data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes); - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - ulsch_input_buffer[0] = 0x31; - for (int i = 1; i < TBS_bytes; i++) { - ulsch_input_buffer[i] = (unsigned char) rand(); - //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - } - //} - - LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n", - ul_info->module_id, - ul_info->frame_tx, - ul_info->slot_tx, - mac->t_crnti); - - // Config UL TX PDU - tx_req.slot = ul_info->slot_tx; - tx_req.sfn = ul_info->frame_tx; - tx_req.number_of_pdus = 1; - tx_req_body.pdu_length = TBS_bytes; - tx_req_body.pdu_index = 0; - tx_req_body.pdu = ulsch_input_buffer; - tx_req.tx_request_body = &tx_req_body; - ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; - ul_config->number_pdus++; - // scheduled_response - fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - mac->if_module->scheduled_response(&scheduled_response); - } - } - } - } - return UE_CONNECTION_OK; -} - -// PUSCH Msg3 scheduled by RAR UL grant according to 8.3 of TS 38.213 -// Note: Msg3 tx in the uplink symbols of mixed slot -void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac, - frame_t current_frame, - sub_frame_t current_slot, - uint8_t Msg3_tda_id){ - - int delta = 0; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; - int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 - // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon - uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[Msg3_tda_id]->k2; - - switch (mu) { - case 0: - delta = 2; - break; - case 1: - delta = 3; - break; - case 2: - delta = 4; - break; - case 3: - delta = 6; - break; - } - - mac->msg3_slot = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; - if (current_slot + k2 + delta > nr_slots_per_frame[mu]) - mac->msg3_frame = (current_frame + 1) % 1024; - else - mac->msg3_frame = current_frame; - - #ifdef DEBUG_MSG3 - LOG_D(MAC, "[DEBUG_MSG3] current_slot %d k2 %d delta %d temp_slot %d mac->msg3_frame %d mac->msg3_slot %d \n", current_slot, k2, delta, current_slot + k2 + delta, mac->msg3_frame, mac->msg3_slot); - #endif -} - -// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x -// It fills the PRACH PDU per each FD occasion. -// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. -// - todo: -// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config -void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { - - uint8_t config_index, mu, N_dur, N_t_slot, start_symbol; - uint16_t format, format0, format1, ncs; - int msg1_FDM, is_nr_prach_slot, fdm; - - NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; - fapi_nr_ul_config_prach_pdu *prach_config_pdu; - fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; - fapi_nr_prach_config_t *prach_config = &cfg->prach_config; - nr_scheduled_response_t scheduled_response; - - NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; - NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; - config_index = rach_ConfigGeneric->prach_ConfigurationIndex; - - mac->RA_offset = 2; // to compensate the rx frame offset at the gNB - mac->generate_nr_prach = 0; // Reset flag for PRACH generation - - if (is_nr_UL_slot(scc, slotP)) { - - if (setup->msg1_SubcarrierSpacing) - mu = *setup->msg1_SubcarrierSpacing; - else - mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; - - is_nr_prach_slot = get_nr_prach_info_from_index(config_index, - (int)frameP, - (int)slotP, - frequencyInfoDL->absoluteFrequencyPointA, - mu, - cfg->cell_config.frame_duplex_type, - &format, - &start_symbol, - &N_t_slot, - &N_dur); - - if (is_nr_prach_slot && mac->ra_state == RA_UE_IDLE) { - - mac->generate_nr_prach = 1; - - fdm = rach_ConfigGeneric->msg1_FDM; - - switch (fdm){ - case 0: - case 1: - case 2: - case 3: - msg1_FDM = 1 << fdm; - break; - default: - AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", fdm); - } - - format0 = format & 0xff; // single PRACH format - format1 = (format >> 8) & 0xff; // dual PRACH format - - ul_config->sfn = frameP; - ul_config->slot = slotP; - - for (int n = 0; n < msg1_FDM; n++) { // one structure per frequency domain occasion - - ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; - prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); - ul_config->number_pdus += 1; - - ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); - - // filling PRACH PDU for FAPI config request - prach_config_pdu->phys_cell_id = *scc->physCellId; - prach_config_pdu->num_prach_ocas = N_t_slot; - prach_config_pdu->prach_start_symbol = start_symbol; - prach_config_pdu->num_ra = n; - prach_config_pdu->num_cs = ncs; - prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[n].prach_root_sequence_index; - prach_config_pdu->restricted_set = prach_config->restricted_set_config; - prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[n].k1; - - if (format1 != 0xff) { - switch(format0) { // dual PRACH format - case 0xa1: - prach_config_pdu->prach_format = 9; - break; - case 0xa2: - prach_config_pdu->prach_format = 10; - break; - case 0xa3: - prach_config_pdu->prach_format = 11; - break; - default: - AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); - } - } else { - switch(format0) { // single PRACH format - case 0xa1: - prach_config_pdu->prach_format = 0; - break; - case 0xa2: - prach_config_pdu->prach_format = 1; - break; - case 0xa3: - prach_config_pdu->prach_format = 2; - break; - case 0xb1: - prach_config_pdu->prach_format = 3; - break; - case 0xb2: - prach_config_pdu->prach_format = 4; - break; - case 0xb3: - prach_config_pdu->prach_format = 5; - break; - case 0xb4: - prach_config_pdu->prach_format = 6; - break; - case 0xc0: - prach_config_pdu->prach_format = 7; - break; - case 0xc2: - prach_config_pdu->prach_format = 8; - break; - case 0: - // long formats are handled @ PHY - break; - case 1: - // long formats are handled @ PHY - break; - case 2: - // long formats are handled @ PHY - break; - case 3: - // long formats are handled @ PHY - break; - default: - AssertFatal(1 == 0, "Invalid PRACH format"); - } - } - } - } - - fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); - } -} - -//////////////////////////////////////////////////////////////////////////// -/////////* Random Access Contention Resolution (5.1.35 TS 38.321) *///////// -//////////////////////////////////////////////////////////////////////////// -// Handling contention resolution timer -// WIP todo: -// - beam failure recovery -// - RA completed - -void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){ - - NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; - - if (mac->RA_contention_resolution_timer_active == 1) { - if (nr_rach_ConfigCommon){ - LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n", - tx_frame, - mac->RA_contention_resolution_cnt, - ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)); - mac->RA_contention_resolution_cnt++; - - if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) { - mac->t_crnti = 0; - mac->RA_active = 0; - mac->RA_contention_resolution_timer_active = 0; - // Signal PHY to quit RA procedure - LOG_E(MAC, "[UE %u] [RAPROC] Contention resolution timer expired, RA failed, discarded TC-RNTI\n", module_id); - nr_ra_failed(module_id, cc_id, gNB_index); - } - } - } -} - -#if 0 -uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, - uint8_t slot, - 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; jnumber_rbs = NRRIV2BW(riv,n_RB_DLBWP); dlsch_config_pdu->start_rb = NRRIV2PRBOFFSET(riv,n_RB_DLBWP); + // Sanity check in case a false or erroneous DCI is received + if ((dlsch_config_pdu->number_rbs < 1 ) || (dlsch_config_pdu->number_rbs > n_RB_DLBWP - dlsch_config_pdu->start_rb)) { + // DCI is invalid! + LOG_W(MAC, "Frequency domain assignment values are invalid! #RBs: %d, Start RB: %d, n_RB_DLBWP: %d \n", dlsch_config_pdu->number_rbs, dlsch_config_pdu->start_rb, n_RB_DLBWP); + return -1; + } + + LOG_D(MAC,"riv = %i\n", riv); + LOG_D(MAC,"n_RB_DLBWP = %i\n", n_RB_DLBWP); + LOG_D(MAC,"number_rbs = %i\n", dlsch_config_pdu->number_rbs); + LOG_D(MAC,"start_rb = %i\n", dlsch_config_pdu->start_rb); + } if(pusch_config_pdu != NULL){ /* @@ -2223,6 +222,14 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p pusch_config_pdu->rb_size = NRRIV2BW(riv,n_RB_ULBWP); pusch_config_pdu->rb_start = NRRIV2PRBOFFSET(riv,n_RB_ULBWP); + + // Sanity check in case a false or erroneous DCI is received + if ((pusch_config_pdu->rb_size < 1) || (pusch_config_pdu->rb_size > n_RB_ULBWP - pusch_config_pdu->rb_start)) { + // DCI is invalid! + LOG_W(MAC, "Frequency domain assignment values are invalid! #RBs: %d, Start RB: %d, n_RB_ULBWP: %d \n",pusch_config_pdu->rb_size, pusch_config_pdu->rb_start, n_RB_ULBWP); + return -1; + } + } return 0; } @@ -2233,7 +240,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind ){ int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position; - uint8_t k_offset=0; +// uint8_t k_offset=0; uint8_t sliv_S=0; uint8_t sliv_L=0; uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 @@ -2372,9 +379,14 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, SLIV2SL(startSymbolAndLength,&S,&L); dlsch_config_pdu->start_symbol=S; dlsch_config_pdu->number_symbols=L; + + LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength); + LOG_D(MAC,"start_symbol = %i\n", dlsch_config_pdu->start_symbol); + LOG_D(MAC,"number_symbols = %i\n", dlsch_config_pdu->number_symbols); + } else {// Default configuration from tables - k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; +// 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]; @@ -2417,7 +429,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pusch_config_pdu->nr_of_symbols=L; } else { - k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0]; +// 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]; @@ -2429,40 +441,40 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, } 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) { + +int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); 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); - int dci_format = nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15); - return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci_format)); + uint32_t dci_format = nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15); + return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci_format)); } -int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){ - - int bwp_id = 1; +int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format){ + int ret = 0; + int pucch_res_set_cnt = 0, valid = 0; + frame_t frame_tx = 0; + int slot_tx = 0; + bool valid_ptrs_setup = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + RA_config_t *ra = &mac->ra; fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; - + uint8_t is_Msg3 = 0; + //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 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"); - const uint16_t n_RB_DLBWP = (mac->ra_state == WAIT_RAR) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); - const uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + const uint16_t n_RB_DLBWP = (ra->ra_state == WAIT_RAR) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - LOG_D(MAC,"nr_ue_process_dci at MAC layer with dci_format=%d (DL BWP %d, UL BWP %d)\n",dci_format,n_RB_DLBWP,n_RB_ULBWP); - - NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; - NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; + LOG_D(MAC, "In %s: Processing received DCI format %s (DL BWP %d)\n", __FUNCTION__, dci_formats[dci_format], n_RB_DLBWP); switch(dci_format){ - case NR_UL_DCI_FORMAT_0_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: @@ -2477,48 +489,42 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc * 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_TYPE_PUSCH; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti; - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_0 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - /* IDENTIFIER_DCI_FORMATS */ - /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ - nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->frequency_domain_assignment.val); - /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_0,NULL,dci->time_domain_assignment.val) < 0) - return -1; - /* 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)) - pusch_config_pdu_0_0->frequency_hopping = dci->frequency_hopping_flag.val; + // Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, + // where K2 is the offset between the slot in which UL DCI is received and the slot + // in which ULSCH should be scheduled. K2 is configured in RRC configuration. + // todo: + // - SUL_IND_0_0 - /* MCS */ - pusch_config_pdu_0_0->mcs_index = dci->mcs; - /* NDI */ - pusch_config_pdu_0_0->pusch_data.new_data_indicator = dci->ndi; - /* RV */ - pusch_config_pdu_0_0->pusch_data.rv_index = dci->rv; - /* HARQ_PROCESS_NUMBER */ - pusch_config_pdu_0_0->pusch_data.harq_process_id = dci->harq_pid; - /* TPC_PUSCH */ - // according to TS 38.213 Table Table 7.1.1-1 - if (dci->tpc == 0) { - pusch_config_pdu_0_0->absolute_delta_PUSCH = -4; - } - if (dci->tpc == 1) { - pusch_config_pdu_0_0->absolute_delta_PUSCH = -1; - } - if (dci->tpc == 2) { - pusch_config_pdu_0_0->absolute_delta_PUSCH = 1; - } - if (dci->tpc == 3) { - pusch_config_pdu_0_0->absolute_delta_PUSCH = 4; - } - /* SUL_IND_0_0 */ // To be implemented, FIXME!!! + // Schedule PUSCH + ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, dci->time_domain_assignment.val); - ul_config->number_pdus = ul_config->number_pdus + 1; + if (ret != -1){ + + // Get UL config request corresponding slot_tx + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + + if (!ul_config) { + LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); + return -1; + } + + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; + + fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + + // Config PUSCH PDU + ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); + + if (ret != -1 && ra->RA_active && mac->crnti){ + nr_ra_succeeded(module_id, frame, slot); + } + + } + break; + } - case NR_UL_DCI_FORMAT_0_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: @@ -2547,304 +553,41 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc * 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_TYPE_PUSCH; - ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu.rnti = rnti; - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu_0_1 = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - /* IDENTIFIER_DCI_FORMATS */ - /* CARRIER_IND */ - /* SUL_IND_0_1 */ - /* BANDWIDTH_PART_IND */ - //pusch_config_pdu_0_1->bandwidth_part_ind = dci->bwp_indicator.val; - /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ - nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->frequency_domain_assignment.val); - /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,dci->time_domain_assignment.val) < 0) - return -1; - /* 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)) - pusch_config_pdu_0_1->frequency_hopping = dci->frequency_hopping_flag.val; - /* MCS */ - pusch_config_pdu_0_1->mcs_index = dci->mcs; - /* MCS TABLE */ - if (pusch_config->transformPrecoder == NULL) { - if (mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - pusch_config_pdu_0_1->transform_precoding = 1; - else - pusch_config_pdu_0_1->transform_precoding = 0; + // TODO: + // - FIRST_DAI + // - SECOND_DAI + // - SRS_RESOURCE_IND + + // Schedule PUSCH + ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, dci->time_domain_assignment.val); + + if (ret != -1){ + + // Get UL config request corresponding slot_tx + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + + if (!ul_config) { + LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); + return -1; + } + + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; + + fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + + // Config PUSCH PDU + ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format); + + if (ret != -1 && ra->RA_active && mac->crnti){ + nr_ra_succeeded(module_id, frame, slot); + } + } - else - pusch_config_pdu_0_1->transform_precoding = *pusch_config->transformPrecoder; - - if (pusch_config_pdu_0_1->transform_precoding == transform_precoder_disabled) - pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_Table, 0, - dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false); - else - pusch_config_pdu_0_1->mcs_table = get_pusch_mcs_table(pusch_config->mcs_TableTransformPrecoder, 1, - dci_format, NR_RNTI_C, NR_SearchSpace__searchSpaceType_PR_ue_Specific, false); - - /* NDI */ - pusch_config_pdu_0_1->pusch_data.new_data_indicator = dci->ndi; - /* RV */ - pusch_config_pdu_0_1->pusch_data.rv_index = dci->rv; - /* HARQ_PROCESS_NUMBER */ - pusch_config_pdu_0_1->pusch_data.harq_process_id = dci->harq_pid; - /* FIRST_DAI */ //To be implemented, FIXME!!! - /* SECOND_DAI */ //To be implemented, FIXME!!! - /* TPC_PUSCH */ - // according to TS 38.213 Table Table 7.1.1-1 - if (dci->tpc == 0) { - pusch_config_pdu_0_1->absolute_delta_PUSCH = -4; - } - if (dci->tpc == 1) { - pusch_config_pdu_0_1->absolute_delta_PUSCH = -1; - } - if (dci->tpc == 2) { - pusch_config_pdu_0_1->absolute_delta_PUSCH = 1; - } - if (dci->tpc == 3) { - pusch_config_pdu_0_1->absolute_delta_PUSCH = 4; - } - /* 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)){ - uint8_t n_antenna_port = 0; //FIXME!!! - if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits - if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook - // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 - 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.max_rank == 2) || - (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 3) || - (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 4))){ - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; - } - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_partialAndNonCoherent){ - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; - } - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){ - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; - } - } - // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 - 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.transform_precoder == transform_precoder_disabled)) - && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 1)){ - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; - } - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_partialAndNonCoherent){ - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; - } - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){ - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; - } - } - } - if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook - // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 - 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.max_rank == 2)){ - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; - } - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){ - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; - } - } - // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 - 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.transform_precoder == transform_precoder_disabled)) - && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 1)){ - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; - } - if (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.codebook_subset == codebook_subset_nonCoherent){ - pusch_config_pdu_0_1->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; - pusch_config_pdu_0_1->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; - } - } - } - } - /* 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 - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = dci->antenna_ports.val; //TBC - } - 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 == 2)) { // tables 7.3.1.1.2-7 - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val); //TBC - //pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME - } - 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.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-8/9/10/11 - if (rank == 1){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC - pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val); //TBC - } - if (rank == 2){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0; - //pusch_config_pdu_0_1->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1; - } - if (rank == 3){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = 0; - //pusch_config_pdu_0_1->dmrs_ports[1] = 1; - //pusch_config_pdu_0_1->dmrs_ports[2] = 2; - } - if (rank == 4){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = 0; - //pusch_config_pdu_0_1->dmrs_ports[1] = 1; - //pusch_config_pdu_0_1->dmrs_ports[2] = 2; - //pusch_config_pdu_0_1->dmrs_ports[3] = 3; - } - } - 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.dmrs_type == 1) && - (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-12/13/14/15 - if (rank == 1){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC - pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC - //pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports.val > 6)?2:1; //FIXME - } - if (rank == 2){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_13[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_13[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; // FIXME - } - if (rank == 3){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_14[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_14[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_14[dci->antenna_ports.val][3]; - //pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME - } - if (rank == 4){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_15[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_15[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_15[dci->antenna_ports.val][3]; - //pusch_config_pdu_0_1->dmrs_ports[3] = table_7_3_1_1_2_15[dci->antenna_ports.val][4]; - //pusch_config_pdu_0_1->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME - } - } - 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.dmrs_type == 2) && - (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-16/17/18/19 - if (rank == 1){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val > 5)?3:2):1; //TBC - pusch_config_pdu_0_1->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC - } - if (rank == 2){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?((dci->antenna_ports.val > 2)?3:2):1; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_17[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_17[dci->antenna_ports.val][2]; - } - if (rank == 3){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?3:2; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_18[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_18[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_18[dci->antenna_ports.val][3]; - } - if (rank == 4){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = dci->antenna_ports.val + 2; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = 0; - //pusch_config_pdu_0_1->dmrs_ports[1] = 1; - //pusch_config_pdu_0_1->dmrs_ports[2] = 2; - //pusch_config_pdu_0_1->dmrs_ports[3] = 3; - } - } - 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.dmrs_type == 2) && - (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-20/21/22/23 - if (rank == 1){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC - pusch_config_pdu_0_1->dmrs_ports = table_7_3_1_1_2_20[dci->antenna_ports.val][1]; //TBC - //pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports.val][2]; //FIXME - } - if (rank == 2){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_21[dci->antenna_ports.val][0]; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports.val][3]; //FIXME - } - if (rank == 3){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_22[dci->antenna_ports.val][0]; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_22[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_22[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_22[dci->antenna_ports.val][3]; - //pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports.val][4]; //FIXME - } - if (rank == 4){ - pusch_config_pdu_0_1->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_23[dci->antenna_ports.val][0]; //TBC - pusch_config_pdu_0_1->dmrs_ports = 0; //FIXME - //pusch_config_pdu_0_1->dmrs_ports[0] = table_7_3_1_1_2_23[dci->antenna_ports.val][1]; - //pusch_config_pdu_0_1->dmrs_ports[1] = table_7_3_1_1_2_23[dci->antenna_ports.val][2]; - //pusch_config_pdu_0_1->dmrs_ports[2] = table_7_3_1_1_2_23[dci->antenna_ports.val][3]; - //pusch_config_pdu_0_1->dmrs_ports[3] = table_7_3_1_1_2_23[dci->antenna_ports.val][4]; - //pusch_config_pdu_0_1->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME - } - } - /* 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!!! - //pusch_config_pdu_0_1->srs_config.aperiodicSRS_ResourceTrigger = (dci->srs_request.val & 0x11); // as per Table 7.3.1.1.2-24 TS 38.212 //FIXME - /* CSI_REQUEST */ - //pusch_config_pdu_0_1->csi_reportTriggerSize = dci->csi_request.val; //FIXME - /* CBGTI */ - //pusch_config_pdu_0_1->maxCodeBlockGroupsPerTransportBlock = dci->cbgti.val; //FIXME - /* 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) && - (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.max_rank == 1))){ - } else { - //pusch_config_pdu_0_1->ptrs_dmrs_association_port = dci->ptrs_dmrs_association.val; //FIXME - } - /* BETA_OFFSET_IND */ - // Table 9.3-3 in [5, TS 38.213] - //pusch_config_pdu_0_1->beta_offset_ind = dci->beta_offset_indicator.val; //FIXME - /* DMRS_SEQ_INI */ - // FIXME!! - /* UL_SCH_IND */ - // A 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 - ul_config->number_pdus = ul_config->number_pdus + 1; break; + } - case NR_DL_DCI_FORMAT_1_0: + case NR_DL_DCI_FORMAT_1_0: { /* * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI * 0 IDENTIFIER_DCI_FORMATS: @@ -2897,21 +640,44 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc */ 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; + NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup; + uint16_t BWPSize = 0; + + if(rnti == SI_RNTI) { + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH; + dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs; + dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb; + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon; + pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2' + BWPSize = dlsch_config_pdu_1_0->BWPSize; + } else { + if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){ + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH; + } else { + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; + } + dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + BWPSize = n_RB_DLBWP; + } + /* 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->frequency_domain_assignment.val); - /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0) + if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,BWPSize,dci->frequency_domain_assignment.val) < 0) { + LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); return -1; + } + /* TIME_DOM_RESOURCE_ASSIGNMENT */ + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0) { + LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } /* 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->start_symbol+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 ? 0 : 1; /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */ if (dlsch_config_pdu_1_0->number_symbols == 2) @@ -2920,8 +686,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 2; /* VRB_TO_PRB_MAPPING */ dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; + /* MCS TABLE INDEX */ + dlsch_config_pdu_1_0->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0; /* MCS */ dlsch_config_pdu_1_0->mcs = dci->mcs; + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dlsch_config_pdu_1_0->mcs > 28) { + LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_0->mcs); + return -1; + } /* NDI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ dlsch_config_pdu_1_0->ndi = dci->ndi; /* RV (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ @@ -2952,6 +725,20 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc //if (dci->pucch_resource_indicator == 6) dlsch_config_pdu_1_0->pucch_resource_id = 7; //pucch-ResourceId obtained from the 7th value of resourceList FIXME!! //if (dci->pucch_resource_indicator == 7) dlsch_config_pdu_1_0->pucch_resource_id = 8; //pucch-ResourceId obtained from the 8th value of resourceList FIXME!! dlsch_config_pdu_1_0->pucch_resource_id = dci->pucch_resource_indicator; + // Sanity check for pucch_resource_indicator value received to check for false DCI. + valid = 0; + pucch_res_set_cnt = mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count; + for (int id = 0; id < pucch_res_set_cnt; id++) { + if (dlsch_config_pdu_1_0->pucch_resource_id < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { + valid = 1; + break; + } + } + if (!valid) { + LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_0->pucch_resource_id); + return -1; + } + /* PDSCH_TO_HARQ_FEEDBACK_TIME_IND (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/ dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = dci->pdsch_to_harq_feedback_timing_indicator.val; @@ -2978,20 +765,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc dlsch_config_pdu_1_0->pucch_resource_id, dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind); - if (mac->RA_window_cnt >= 0 && rnti == mac->ra_rnti){ - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH; - } else { - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; - } - // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type); dl_config->number_pdus = dl_config->number_pdus + 1; break; + } - case NR_DL_DCI_FORMAT_1_1: + case NR_DL_DCI_FORMAT_1_1: { /* * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI * 0 IDENTIFIER_DCI_FORMATS: @@ -3021,6 +803,15 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc * 44 CBGFI: * 47 DMRS_SEQ_INI: */ + + if (dci->bwp_indicator.val != 1) { + LOG_W(MAC, "[%d.%d] bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } + config_bwp_ue(mac, &dci->bwp_indicator.val, &dci_format); + NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id; + NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup; + 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].dlsch_config_pdu.rnti = rnti; fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15; @@ -3029,15 +820,20 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc /* 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->frequency_domain_assignment.val); - /* TIME_DOM_RESOURCE_ASSIGNMENT */ - if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0) + if (nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->frequency_domain_assignment.val) < 0) { + LOG_W(MAC, "[%d.%d] Invalid frequency_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); return -1; + } + /* TIME_DOM_RESOURCE_ASSIGNMENT */ + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0) { + LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot); + return -1; + } /* dmrs symbol positions*/ dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, dlsch_config_pdu_1_1->number_symbols); - dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; + dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214, using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */ dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1; @@ -3052,12 +848,22 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc dlsch_config_pdu_1_1->zp_csi_rs_trigger = dci->zp_csi_rs_trigger.val; /* MCS (for transport block 1)*/ dlsch_config_pdu_1_1->mcs = dci->mcs; + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dlsch_config_pdu_1_1->mcs > 28) { + LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->mcs); + return -1; + } /* NDI (for transport block 1)*/ dlsch_config_pdu_1_1->ndi = dci->ndi; /* RV (for transport block 1)*/ dlsch_config_pdu_1_1->rv = dci->rv; /* MCS (for transport block 2)*/ dlsch_config_pdu_1_1->tb2_mcs = dci->mcs2.val; + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dlsch_config_pdu_1_1->tb2_mcs > 28) { + LOG_W(MAC, "[%d.%d] MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->tb2_mcs); + return -1; + } /* NDI (for transport block 2)*/ dlsch_config_pdu_1_1->tb2_ndi = dci->ndi2.val; /* RV (for transport block 2)*/ @@ -3074,9 +880,24 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc if (dci->tpc == 3) dlsch_config_pdu_1_1->accumulated_delta_PUCCH = 3; /* PUCCH_RESOURCE_IND */ dlsch_config_pdu_1_1->pucch_resource_id = dci->pucch_resource_indicator; + // Sanity check for pucch_resource_indicator value received to check for false DCI. + valid = 0; + pucch_res_set_cnt = mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.count; + for (int id = 0; id < pucch_res_set_cnt; id++) { + if (dlsch_config_pdu_1_1->pucch_resource_id < mac->ULbwp[0]->bwp_Dedicated->pucch_Config->choice.setup->resourceSetToAddModList->list.array[id]->resourceList.list.count) { + valid = 1; + break; + } + } + if (!valid) { + LOG_W(MAC, "[%d.%d] pucch_resource_indicator value %d is out of bounds. Possibly due to false DCI. Ignoring DCI!\n", frame, slot, dlsch_config_pdu_1_1->pucch_resource_id); + return -1; + } + /* 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->ULbwp[bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0]; + NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; + dlsch_config_pdu_1_1->pdsch_to_harq_feedback_time_ind = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0]; /* 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) && @@ -3178,8 +999,22 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc 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; + /* TODO same calculation for MCS table as done in UL */ + dlsch_config_pdu_1_1->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0; + /*PTRS configuration */ + if(mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS != NULL) { + valid_ptrs_setup = set_dl_ptrs_values(mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup, + dlsch_config_pdu_1_1->number_rbs, dlsch_config_pdu_1_1->mcs, dlsch_config_pdu_1_1->mcs_table, + &dlsch_config_pdu_1_1->PTRSFreqDensity,&dlsch_config_pdu_1_1->PTRSTimeDensity, + &dlsch_config_pdu_1_1->PTRSPortIndex,&dlsch_config_pdu_1_1->nEpreRatioOfPDSCHToPTRS, + &dlsch_config_pdu_1_1->PTRSReOffset, dlsch_config_pdu_1_1->number_symbols); + if(valid_ptrs_setup==true) { + dlsch_config_pdu_1_1->pduBitmap |= 0x1; + } + } break; + } case NR_DL_DCI_FORMAT_2_0: break; @@ -3213,7 +1048,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc /// else normal DL-SCH grant } - return 0; + + return ret; + } 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){ @@ -3221,29 +1058,10 @@ int8_t nr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t e return 0; } -void nr_ue_send_sdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - int slotP, - uint8_t * pdu, uint16_t pdu_len, uint8_t gNB_index, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ - - LOG_D(MAC, "Handling PDU frame %d slot %d\n", frameP, slotP); - - uint8_t * pduP = pdu; +void nr_ue_send_sdu(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); - //LOG_D(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]); - - /* - #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE %d] ue_send_sdu : Frame %d gNB_index %d : num_ce %d num_sdu %d\n", - module_idP, frameP, gNB_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++) { @@ -3251,12 +1069,21 @@ void nr_ue_send_sdu(module_id_t module_idP, } LOG_T(MAC, "\n"); #endif - */ + + LOG_D(MAC, "In %s [%d.%d] Handling DLSCH PDU...\n", __FUNCTION__, dl_info->frame, dl_info->slot); // Processing MAC PDU // it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs - if (pduP != NULL) - nr_ue_process_mac_pdu(module_idP, CC_id, frameP, pduP, pdu_len, gNB_index, ul_time_alignment); + switch (dl_info->rx_ind->rx_indication_body[pdu_id].pdu_type){ + case FAPI_NR_RX_PDU_TYPE_DLSCH: + nr_ue_process_mac_pdu(dl_info, ul_time_alignment, pdu_id); + break; + case FAPI_NR_RX_PDU_TYPE_RAR: + nr_ue_process_rar(dl_info, ul_time_alignment, pdu_id); + break; + default: + break; + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT); @@ -3269,46 +1096,43 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){ switch(rnti_type) { case NR_RNTI_RA: case NR_RNTI_TC: - case NR_RNTI_P: - case NR_RNTI_SI: - if (mac->DLbwp[0]->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero) { - uint8_t bwp_id = 1; + case NR_RNTI_P: { + NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id; + if (mac->DLbwp[dl_bwp_id-1]->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero) { uint8_t coreset_id = 0; // assuming controlResourceSetId is 0 for controlResourceSetZero - NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id]; + NR_ControlResourceSet_t *coreset = mac->coreset[dl_bwp_id-1][coreset_id]; get_coreset_rballoc(coreset->frequencyDomainResources.buf,&N_RB,&start_RB); } else { - N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } break; + } + case NR_RNTI_SI: + N_RB = mac->type0_PDCCH_CSS_config.num_rbs; + break; case NR_RNTI_C: - N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, 275); - break; + N_RB = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + break; } return N_RB; } -int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, - int dci_format, +uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, + uint8_t dci_format, uint8_t dci_size, uint16_t rnti, uint64_t *dci_pdu, 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; + int rnti_type = get_rnti_type(mac, rnti); - 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 = get_n_rb(mac, rnti_type); int N_RB_UL = (mac->scg != NULL) ? - NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275) : - NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); + NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : + NRRIV2BW(mac->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int pos=0; int fsize=0; @@ -3492,10 +1316,10 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, case NR_RNTI_P: /* - // Short Messages Indicator – 2 bits + // Short Messages Indicator  E2 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 + // Short Messages  E8 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 @@ -3519,23 +1343,42 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, 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.val&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++); - */ + + // Freq domain assignment 0-16 bit + fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); + pos+=fsize; + dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; + + // VRB to PRB mapping 1 bit + pos++; + dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&0x1; + + // MCS 5bit //bit over 32, so dci_pdu ++ + pos+=5; + dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f; + + // Redundancy version 2 bit + pos+=2; + dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3; + + // System information indicator 1 bit + pos++; + dci_pdu_rel15->system_info_indicator = (*dci_pdu>>(dci_size-pos))&0x1; + + LOG_D(MAC,"N_RB = %i\n", N_RB); + LOG_D(MAC,"dci_size = %i\n", dci_size); + LOG_D(MAC,"fsize = %i\n", fsize); + LOG_D(MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + LOG_D(MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + LOG_D(MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + LOG_D(MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); + LOG_D(MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + LOG_D(MAC,"dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator); + break; case NR_RNTI_TC: @@ -3562,13 +1405,13 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // HARQ process number 4bit pos+=4; dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; - // Downlink assignment index – 2 bits + // Downlink assignment index  E2 bits pos+=2; dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3; - // TPC command for scheduled PUCCH – 2 bits + // TPC command for scheduled PUCCH  E2 bits pos+=2; dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; - // PDSCH-to-HARQ_feedback timing indicator – 3 bits + // PDSCH-to-HARQ_feedback timing indicator  E3 bits pos+=3; dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&7; @@ -3586,10 +1429,9 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // Time domain assignment 4bit pos+=4; dci_pdu_rel15->time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf; - // This is not supported yet - Skip for now - // Frequency hopping flag – 1 bit - //pos++; - //dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; + // Frequency hopping flag  E1 bit + pos++; + dci_pdu_rel15->frequency_hopping_flag.val= (*dci_pdu>>(dci_size-pos))&1; // MCS 5 bit pos+=5; dci_pdu_rel15->mcs= (*dci_pdu>>(dci_size-pos))&0x1f; @@ -3602,10 +1444,10 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // HARQ process number 4bit pos+=4; dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf; - // TPC command for scheduled PUSCH – 2 bits + // TPC command for scheduled PUSCH  E2 bits pos+=2; dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3; - // UL/SUL indicator – 1 bit + // UL/SUL indicator  E1 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++); @@ -3623,7 +1465,7 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // 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 + // Frequency hopping flag  E1 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++) @@ -3637,11 +1479,11 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, 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 + // TPC command for scheduled PUSCH  E2 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 + // UL/SUL indicator  E1 bit /* commented for now (RK): need to get this information from BWP descriptor if (cfg->pucch_config.pucch_GroupHopping.value) @@ -3752,7 +1594,7 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // BWP Indicator pos+=dci_pdu_rel15->bwp_indicator.nbits; dci_pdu_rel15->bwp_indicator.val = (*dci_pdu>>(dci_size-pos))&((1<bwp_indicator.nbits)-1); - + // Freq domain assignment max 16 bit fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); //pos+=dci_pdu_rel15->frequency_domain_assignment.nbits; @@ -3852,70 +1694,81 @@ int nr_extract_dci_info(NR_UE_MAC_INST_t *mac, return dci_format; } +/////////////////////////////////// +// brief: nr_ue_process_mac_pdu +// function: parsing DL PDU header +/////////////////////////////////// +// Header for DLSCH: +// Except: +// - DL-SCH: fixed-size MAC CE(known by LCID) +// - DL-SCH: padding +// +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// |0|1|2|3|4|5|6|7| bit-wise +// |R|F| LCID | +// | L | +// | L | +//////////////////////////////// +// Header for DLSCH: +// - DLSCH: fixed-size MAC CE(known by LCID) +// - DLSCH: padding, for single/multiple 1-oct padding CE(s) +// +// |0|1|2|3|4|5|6|7| bit-wise +// |R|R| LCID | +// LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described +// in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; +// L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders +// corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; +// F: lenght of L is 0:8 or 1:16 bits wide +// R: Reserved bit, set to zero. +//////////////////////////////// +void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, + int pdu_id){ -void nr_ue_process_mac_pdu(module_id_t module_idP, - uint8_t CC_id, - frame_t frameP, - uint8_t *pduP, - uint16_t mac_pdu_len, - uint8_t gNB_index, - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ + uint8_t rx_lcid; + uint16_t mac_ce_len; + uint16_t mac_subheader_len; + uint16_t mac_sdu_len; + module_id_t module_idP = dl_info->module_id; + frame_t frameP = dl_info->frame; + int slot = dl_info->slot; + uint8_t *pduP = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu; + uint16_t pdu_len = (dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu.pdu_length; + uint8_t gNB_index = dl_info->gNB_index; + uint8_t CC_id = dl_info->cc_id; + uint8_t done = 0; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + RA_config_t *ra = &mac->ra; - // This function is adapting code from the old - // parse_header(...) and ue_send_sdu(...) functions of OAI LTE + if (!pduP){ + return; + } - uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; - int pdu_len = mac_pdu_len; - uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; - NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + LOG_D(MAC, "In %s [%d.%d]: processing PDU %d of %d total number of PDUs...\n", __FUNCTION__, frameP, slot, pdu_id, dl_info->rx_ind->number_pdus); - //NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); - //uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; - //uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB; - - // For both DL/UL-SCH - // Except: - // - UL/DL-SCH: fixed-size MAC CE(known by LCID) - // - UL/DL-SCH: padding - // - UL-SCH: MSG3 48-bits - // |0|1|2|3|4|5|6|7| bit-wise - // |R|F| LCID | - // | L | - // |0|1|2|3|4|5|6|7| bit-wise - // |R|F| LCID | - // | L | - // | L | - - // For both DL/UL-SCH - // For: - // - UL/DL-SCH: fixed-size MAC CE(known by LCID) - // - UL/DL-SCH: padding, for single/multiple 1-oct padding CE(s) - // - UL-SCH: MSG3 48-bits - // |0|1|2|3|4|5|6|7| bit-wise - // |R|R| LCID | - // LCID: The Logical Channel ID field identifies the logical channel instance of the corresponding MAC SDU or the type of the corresponding MAC CE or padding as described in Tables 6.2.1-1 and 6.2.1-2 for the DL-SCH and UL-SCH respectively. There is one LCID field per MAC subheader. The LCID field size is 6 bits; - // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; - // F: lenght of L is 0:8 or 1:16 bits wide - // R: Reserved bit, set to zero. while (!done && pdu_len > 0){ mac_ce_len = 0x0000; mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct mac_sdu_len = 0x0000; - rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID; //#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pduP)->LCID, pdu_len); //#endif + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", rx_lcid, pdu_len); switch(rx_lcid){ // MAC CE case DL_SCH_LCID_CCCH: // MSG4 RRC Connection Setup 38.331 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } @@ -3925,40 +1778,40 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, // 38.321 Ch6.1.3.14 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } break; case DL_SCH_LCID_APERIODIC_CSI_TRI_STATE_SUBSEL: // 38.321 Ch6.1.3.13 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } break; case DL_SCH_LCID_SP_CSI_RS_CSI_IM_RES_SET_ACT: // 38.321 Ch6.1.3.12 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } break; case DL_SCH_LCID_SP_SRS_ACTIVATION: // 38.321 Ch6.1.3.17 // varialbe length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; } break; @@ -4009,52 +1862,33 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, // 38.321 Ch6.1.3.4 mac_ce_len = 1; - /*uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND; - uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID;*/ + /*uint8_t ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND; + uint8_t tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID;*/ ul_time_alignment->apply_ta = 1; - ul_time_alignment->ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND; - ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID; + ul_time_alignment->ta_command = ((NR_MAC_CE_TA *)pduP)[1].TA_COMMAND; + ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pduP)[1].TAGID; /* #ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pdu_ptr[1]); + LOG_D(MAC, "[UE] CE %d : UE Timing Advance : %d\n", i, pduP[1]); #endif */ - LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); + LOG_I(MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); break; case DL_SCH_LCID_CON_RES_ID: - // 38.321 Ch6.1.3.3 + // Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16 // WIP todo: handle CCCH_pdu mac_ce_len = 6; - LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pdu_ptr[0], pdu_ptr[1], pdu_ptr[2], pdu_ptr[3], pdu_ptr[4], pdu_ptr[5]); + LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pduP[0], pduP[1], pduP[2], pduP[3], pduP[4], pduP[5]); - if (mac->RA_active == 1) { - LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP); - mac->RA_active = 0; - // // check if RA procedure has finished completely (no contention) - // tx_sdu = &mac->CCCH_pdu.payload[3]; - // //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits) - // // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or // SCH_SUBHEADER_SHORT) - // for (i = 0; i < 6; i++) - // if (tx_sdu[i] != payload_ptr[i]) { - // LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP); - // nr_ra_failed(module_idP, CC_id, eNB_index); - // mac->RA_contention_resolution_timer_active = 0; - // return; - // } - LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Cleared contention resolution timer. Set C-RNTI to TC-RNTI\n", - module_idP, - frameP); - mac->RA_contention_resolution_timer_active = 0; - nr_ra_succeeded(module_idP, CC_id, gNB_index); - mac->crnti = mac->t_crnti; - mac->t_crnti = 0; - mac->ra_state = RA_SUCCEEDED; + if (ra->RA_active == 1) { + nr_ra_succeeded(module_idP, frameP, slot); } + break; case DL_SCH_LCID_PADDING: done = 1; @@ -4071,14 +1905,14 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, default: // check if LCID is valid at current time. - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; + if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; mac_subheader_len = 3; - mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8) - | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff); + mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8) + | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff); } else { - mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; mac_subheader_len = 2; } @@ -4088,7 +1922,7 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); for (i = 0; i < 32; i++) - LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); + LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]); LOG_T(MAC, "\n"); #endif @@ -4097,13 +1931,13 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DTCH) { mac_rlc_data_ind(module_idP, - 0x1234, + mac->crnti, gNB_index, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), + (char *) (pduP + mac_subheader_len), mac_sdu_len, 1, NULL); @@ -4114,7 +1948,7 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, break; } - pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); + pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); if (pdu_len < 0) LOG_E(MAC, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", pdu_len); @@ -4212,7 +2046,7 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, if (crnti) { // MAC CE fixed subheader mac_pdu_ptr->R = 0; - mac_pdu_ptr->LCID = CRNTI; + mac_pdu_ptr->LCID = UL_SCH_LCID_C_RNTI; mac_pdu_ptr++; // C-RNTI MAC CE (2 octets) @@ -4296,133 +2130,200 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, return offset; } -uint8_t -nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t subframe, uint8_t eNB_index, - uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { - uint8_t total_rlc_pdu_header_len = 0; - int16_t buflen_remain = 0; - uint8_t lcid = 0; - uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - uint16_t payload_offset = 0, num_sdus = 0; - uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; - uint16_t sdu_length_total = 0; - //unsigned short post_padding = 0; +///////////////////////////////////// +// Random Access Response PDU // +// TS 38.213 ch 8.2 // +// TS 38.321 ch 6.2.3 // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//| E | T | R A P I D |// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// +//| R | T A |// +//| T A | UL grant |// +//| UL grant |// +//| UL grant |// +//| UL grant |// +//| T C - R N T I |// +//| T C - R N T I |// +///////////////////////////////////// +// UL grant (27 bits) // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//|-------------------|FHF|F_alloc|// +//| Freq allocation |// +//| F_alloc |Time allocation|// +//| MCS | TPC |CSI|// +///////////////////////////////////// +// TbD WIP Msg3 development ongoing +// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213 +// - apply tpc command +// WIP fix: +// - time domain indication hardcoded to 0 for k2 offset +// - extend TS 38.213 ch 8.3 Msg3 PUSCH +// - b buffer +// - ulsch power offset +// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures +int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ - rlc_buffer_occupancy_t lcid_buffer_occupancy_old = - 0, lcid_buffer_occupancy_new = 0; - LOG_D(MAC, - "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", - module_idP, frameP, subframe, buflen); - AssertFatal(CC_id == 0, - "Transmission on secondary CCs is not supported yet\n"); -#if UE_TIMING_TRACE - start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu); + module_id_t mod_id = dl_info->module_id; + frame_t frame = dl_info->frame; + int slot = dl_info->slot; + int cc_id = dl_info->cc_id; + uint8_t gNB_id = dl_info->gNB_index; + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + uint8_t n_subPDUs = 0; // number of RAR payloads + uint8_t n_subheaders = 0; // number of MAC RAR subheaders + uint8_t *dlsch_buffer = dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.pdu; + uint8_t is_Msg3 = 1; + frame_t frame_tx = 0; + int slot_tx = 0; + uint16_t rnti = 0; + int ret = 0; + NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer + NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer + uint8_t preamble_index = get_ra_PreambleIndex(mod_id, cc_id, gNB_id); //prach_resources->ra_PreambleIndex; + + LOG_D(MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index); + + while (1) { + n_subheaders++; + if (rarh->T == 1) { + n_subPDUs++; + LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id); + } else { + n_subPDUs++; + ra->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; + ra->RA_BI_found = 1; + LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ra->RA_backoff_indicator); + } + if (rarh->RAPID == preamble_index) { + LOG_I(MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); + rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); + ra->RA_RAPID_found = 1; + break; + } + if (rarh->E == 0) { + LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match the intended RAPID...\n", mod_id, preamble_index); + break; + } else { + rarh += sizeof(NR_MAC_RAR) + 1; + } + } + + #ifdef DEBUG_RAR + LOG_D(MAC, "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", frame, slot, n_subheaders, n_subPDUs); + LOG_D(MAC, "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); + #endif + + if (ra->RA_RAPID_found) { + + RAR_grant_t rar_grant; + + unsigned char tpc_command; +#ifdef DEBUG_RAR + unsigned char csi_req; #endif - //NR_UE_MAC_INST_t *nr_ue_mac_inst = get_mac_inst(0); + // TC-RNTI + ra->t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); - // Check for DCCH first - // TO DO: Multiplex in the order defined by the logical channel prioritization - for (lcid = UL_SCH_LCID_SRB1; - lcid < NR_MAX_NUM_LCID; lcid++) { + // TA command + ul_time_alignment->apply_ta = 1; + ul_time_alignment->ta_command = rar->TA2 + (rar->TA1 << 5); - lcid_buffer_occupancy_old = - //TODO: Replace static value with CRNTI - mac_rlc_get_buffer_occupancy_ind(module_idP, - 0x1234, eNB_index, frameP, //nr_ue_mac_inst->crnti - subframe, ENB_FLAG_NO, - lcid); - lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; - - if(lcid_buffer_occupancy_new){ - - buflen_remain = - buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); - LOG_D(MAC, - "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " - "send (Transport Block size %d SDU Length Total %d , mac header len %d, buflen_remain %d )\n", //BSR byte before Tx=%d - module_idP, frameP, lcid, lcid_buffer_occupancy_new, - buflen, sdu_length_total, - total_rlc_pdu_header_len, buflen_remain); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]] - - while(buflen_remain > 0 && lcid_buffer_occupancy_new){ - - //TODO: Replace static value with CRNTI - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - 0x1234, eNB_index, //nr_ue_mac_inst->crnti - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - buflen_remain, - (char *)&ulsch_sdus[sdu_length_total],0, - 0 - ); - AssertFatal(buflen_remain >= sdu_lengths[num_sdus], - "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", - lcid, sdu_lengths[num_sdus], buflen_remain); - - if (sdu_lengths[num_sdus]) { - sdu_length_total += sdu_lengths[num_sdus]; - sdu_lcids[num_sdus] = lcid; - - total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last; - - //Update number of SDU - num_sdus++; - } - - /* Get updated BO after multiplexing this PDU */ - //TODO: Replace static value with CRNTI - - lcid_buffer_occupancy_new = - mac_rlc_get_buffer_occupancy_ind(module_idP, - 0x1234, //nr_ue_mac_inst->crnti - eNB_index, frameP, - subframe, ENB_FLAG_NO, - lcid); - buflen_remain = - buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); - } - } - -} - - // Generate ULSCH PDU - if (num_sdus>0) { - payload_offset = nr_generate_ulsch_pdu(ulsch_sdus, - ulsch_buffer, // mac header - num_sdus, // num sdus - sdu_lengths, // sdu length - sdu_lcids, // sdu lcid - 0, // power_headroom - 0, // crnti - 0, // truncated_bsr - 0, // short_bsr - 0, // long_bsr - 0, // post_padding - buflen); // TBS in bytes - } - else - return 0; - - // Padding: fill remainder of ULSCH with 0 - if (buflen - payload_offset > 0){ - for (int j = payload_offset; j < buflen; j++) - ulsch_buffer[j] = 0; - } - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_I(MAC, "Printing UL MAC payload UE side, payload_offset: %d \n", payload_offset); - for (int i = 0; i < buflen ; i++) { - //harq_process_ul_ue->a[i] = (unsigned char) rand(); - //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - printf("%02x ",(unsigned char)ulsch_buffer[i]); - } - printf("\n"); +#ifdef DEBUG_RAR + // CSI + csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01); #endif - return 1; + // TPC + tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07); + switch (tpc_command){ + case 0: + ra->Msg3_TPC = -6; + break; + case 1: + ra->Msg3_TPC = -4; + break; + case 2: + ra->Msg3_TPC = -2; + break; + case 3: + ra->Msg3_TPC = 0; + break; + case 4: + ra->Msg3_TPC = 2; + break; + case 5: + ra->Msg3_TPC = 4; + break; + case 6: + ra->Msg3_TPC = 6; + break; + case 7: + ra->Msg3_TPC = 8; + break; + } + // MCS + rar_grant.mcs = (unsigned char) (rar->UL_GRANT_4 >> 4); + // time alloc + rar_grant.Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07); + // frequency alloc + rar_grant.Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); + // frequency hopping + rar_grant.freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); + // TC-RNTI + if (ra->t_crnti) { + rnti = ra->t_crnti; + } else { + rnti = mac->crnti; + } + + #ifdef DEBUG_RAR + LOG_D(MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n", + __FUNCTION__, + frame, + slot, + mod_id, + rar_grant.Msg3_t_alloc, + rar_grant.Msg3_f_alloc, + ul_time_alignment->ta_command, + rar_grant.mcs, + rar_grant.freq_hopping, + tpc_command, + csi_req, + ra->t_crnti); + #endif + + // Schedule Msg3 + ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, rar_grant.Msg3_t_alloc); + + if (ret != -1){ + + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + + if (!ul_config) { + LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); + return -1; + } + + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; + + fill_ul_config(ul_config, frame_tx, slot_tx, FAPI_NR_UL_CONFIG_TYPE_PUSCH); + + // Config Msg3 PDU + nr_config_pusch_pdu(mac, pusch_config_pdu, NULL, &rar_grant, rnti, NULL); + + } + + } else { + + ra->t_crnti = 0; + ul_time_alignment->ta_command = (0xffff); + + } + + return ret; + } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c new file mode 100644 index 0000000000..d6e1cba6df --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -0,0 +1,1897 @@ +/* + * 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_scheduler.c + * \brief Routines for UE scheduling + * \author Guido Casati + * \date Jan 2021 + * \version 0.1 + * \company Fraunhofer IIS + * \email guido.casati@iis.fraunhofer.de + */ + +#include +#include + +/* exe */ +#include + +/* RRC*/ +#include "RRC/NR_UE/rrc_proto.h" +#include "NR_RACH-ConfigCommon.h" +#include "NR_RACH-ConfigGeneric.h" +#include "NR_FrequencyInfoDL.h" +#include "NR_PDCCH-ConfigCommon.h" + +/* MAC */ +#include "NR_MAC_COMMON/nr_mac.h" +#include "NR_MAC_UE/mac_proto.h" +#include "NR_MAC_UE/mac_extern.h" + +/* utils */ +#include "assertions.h" +#include "asn1_conversions.h" +#include "SIMULATION/TOOLS/sim.h" // for taus + +static prach_association_pattern_t prach_assoc_pattern; +static ssb_list_info_t ssb_list; + +void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){ + + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type; + ul_config->slot = slot_tx; + ul_config->sfn = frame_tx; + ul_config->number_pdus++; + + LOG_D(MAC, "In %s: Set config request for UL transmission in [%d.%d], number of UL PDUs: %d\n", __FUNCTION__, ul_config->sfn, ul_config->slot, ul_config->number_pdus); + +} + +void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, + fapi_nr_dl_config_request_t *dl_config, + fapi_nr_ul_config_request_t *ul_config, + fapi_nr_tx_request_t *tx_request, + module_id_t mod_id, + int cc_id, + frame_t frame, + int slot, + int thread_id){ + + scheduled_response->dl_config = dl_config; + scheduled_response->ul_config = ul_config; + scheduled_response->tx_request = tx_request; + scheduled_response->module_id = mod_id; + scheduled_response->CC_id = cc_id; + scheduled_response->frame = frame; + scheduled_response->slot = slot; + scheduled_response->thread_id = thread_id; + +} + +/* + * This function returns the slot offset K2 corresponding to a given time domain + * indication value from RRC configuration. + */ +long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { + long k2 = -1; + // Get K2 from RRC configuration + NR_PUSCH_Config_t *pusch_config=mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; + if (pusch_config->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup; + } + else if (mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + } + if (pusch_TimeDomainAllocationList) { + if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) { + LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n", + time_domain_ind, pusch_TimeDomainAllocationList->list.count); + return -1; + } + k2 = *pusch_TimeDomainAllocationList->list.array[time_domain_ind]->k2; + } + + LOG_D(MAC, "get_k2(): k2 is %ld\n", k2); + return k2; +} + +/* + * This function returns the UL config corresponding to a given UL slot + * from MAC instance . + */ +fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) { + //Check if request to access ul_config is for a UL slot + if (is_nr_UL_slot(mac->scc, slot) == 0) { + LOG_W(MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__); + return NULL; + } + + // Calculate the index of the UL slot in mac->ul_config_request list. This is + // based on the TDD pattern (slot configuration period) and number of UL+mixed + // slots in the period. TS 38.213 Sec 11.1 + int mu = mac->ULbwp[0]->bwp_Common->genericParameters.subcarrierSpacing; + NR_TDD_UL_DL_Pattern_t *tdd_pattern = &mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1; + const int num_slots_per_tdd = nr_slots_per_frame[mu] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); + const int num_slots_ul = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); + int index = (slot + num_slots_ul - num_slots_per_tdd) % num_slots_per_tdd; + + LOG_D(MAC, "In %s slots per tdd %d, num_slots_ul %d, index %d\n", __FUNCTION__, + num_slots_per_tdd, + num_slots_ul, + index); + + return &mac->ul_config_request[index]; +} + +void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { + + fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated; + NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; + + /* PRECOD_NBR_LAYERS */ + if ((pusch_config_dedicated->tx_config == tx_config_nonCodebook)); + // 0 bits if the higher layer parameter txConfig = nonCodeBook + + if ((pusch_config_dedicated->tx_config == tx_config_codebook)){ + + uint8_t n_antenna_port = 0; //FIXME!!! + + if (n_antenna_port == 1); // 1 antenna port and the higher layer parameter txConfig = codebook 0 bits + + if (n_antenna_port == 4){ // 4 antenna port and the higher layer parameter txConfig = codebook + + // Table 7.3.1.1.2-2: transformPrecoder=disabled and maxRank = 2 or 3 or 4 + if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) + && ((pusch_config_dedicated->max_rank == 2) || + (pusch_config_dedicated->max_rank == 3) || + (pusch_config_dedicated->max_rank == 4))){ + + if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][0]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][1]; + } + + if (pusch_config_dedicated->codebook_subset == codebook_subset_partialAndNonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][2]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][3]; + } + + if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][4]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][5]; + } + } + + // Table 7.3.1.1.2-3: transformPrecoder= enabled, or transformPrecoder=disabled and maxRank = 1 + if (((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) + || (pusch_config_dedicated->transform_precoder == transform_precoder_disabled)) + && (pusch_config_dedicated->max_rank == 1)){ + + if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][6]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][7]; + } + + if (pusch_config_dedicated->codebook_subset == codebook_subset_partialAndNonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][8]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][9]; + } + + if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][10]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][11]; + } + } + } + + if (n_antenna_port == 4){ // 2 antenna port and the higher layer parameter txConfig = codebook + // Table 7.3.1.1.2-4: transformPrecoder=disabled and maxRank = 2 + if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && (pusch_config_dedicated->max_rank == 2)){ + + if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][12]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][13]; + } + + if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][14]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][15]; + } + + } + + // Table 7.3.1.1.2-5: transformPrecoder= enabled, or transformPrecoder= disabled and maxRank = 1 + if (((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) + || (pusch_config_dedicated->transform_precoder == transform_precoder_disabled)) + && (pusch_config_dedicated->max_rank == 1)){ + + if (pusch_config_dedicated->codebook_subset == codebook_subset_fullyAndPartialAndNonCoherent) { + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][16]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][17]; + } + + if (pusch_config_dedicated->codebook_subset == codebook_subset_nonCoherent){ + pusch_config_pdu->nrOfLayers = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][18]; + pusch_config_pdu->transform_precoding = table_7_3_1_1_2_2_3_4_5[dci->precoding_information.val][19]; + } + + } + } + } + + /*-------------------- Changed to enable Transform precoding in RF SIM------------------------------------------------*/ + + if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { + + pusch_config_dedicated->transform_precoder = transform_precoder_enabled; + + if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) { + + NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; + + if (NR_DMRS_ulconfig->dmrs_Type == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type = 1; + if (NR_DMRS_ulconfig->maxLength == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length = 1; + + } else if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB != NULL) { + + NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + + if (NR_DMRS_ulconfig->dmrs_Type == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.dmrs_type = 1; + if (NR_DMRS_ulconfig->maxLength == NULL) + pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.max_length = 1; + + } + } else + pusch_config_dedicated->transform_precoder = transform_precoder_disabled; + + // mapping type b configured from RRC. TBD: Mapping type b is not handled in this function. + if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.dmrs_type == 1) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_b.max_length == 1)) { // tables 7.3.1.1.2-6 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; + } +} + +// todo: this function shall be reviewed completely because of the many comments left by the author +void ul_ports_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { + + /* ANTENNA_PORTS */ + uint8_t rank = 0; // We need to initialize rank FIXME!!! + fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated; + + if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-6 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = dci->antenna_ports.val; //TBC + } + + if ((pusch_config_dedicated->transform_precoder == transform_precoder_enabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-7 + + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 3)?(dci->antenna_ports.val-4):(dci->antenna_ports.val); //TBC + //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports > 3)?2:1; //FIXME + } + + if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-8/9/10/11 + + if (rank == 1) { + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC + pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val-2):(dci->antenna_ports.val); //TBC + } + + if (rank == 2){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?0:2):0; + //pusch_config_pdu->dmrs_ports[1] = (dci->antenna_ports > 1)?(dci->antenna_ports > 2 ?2:3):1; + } + + if (rank == 3){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = 0; + //pusch_config_pdu->dmrs_ports[1] = 1; + //pusch_config_pdu->dmrs_ports[2] = 2; + } + + if (rank == 4){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = 0; + //pusch_config_pdu->dmrs_ports[1] = 1; + //pusch_config_pdu->dmrs_ports[2] = 2; + //pusch_config_pdu->dmrs_ports[3] = 3; + } + } + + if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 1) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-12/13/14/15 + + if (rank == 1){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?2:1; //TBC + pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC + //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 6)?2:1; //FIXME + } + + if (rank == 2){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?2:1; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_13[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_13[dci->antenna_ports.val][2]; + //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 3)?2:1; // FIXME + } + + if (rank == 3){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_14[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_14[dci->antenna_ports.val][2]; + //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_14[dci->antenna_ports.val][3]; + //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME + } + + if (rank == 4){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_15[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_15[dci->antenna_ports.val][2]; + //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_15[dci->antenna_ports.val][3]; + //pusch_config_pdu->dmrs_ports[3] = table_7_3_1_1_2_15[dci->antenna_ports.val][4]; + //pusch_config_pdu->n_front_load_symb = (dci->antenna_ports.val > 1)?2:1; //FIXME + } + } + + if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 1)) { // tables 7.3.1.1.2-16/17/18/19 + + if (rank == 1){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 1)?((dci->antenna_ports.val > 5)?3:2):1; //TBC + pusch_config_pdu->dmrs_ports = (dci->antenna_ports.val > 1)?(dci->antenna_ports.val > 5 ?(dci->antenna_ports.val-6):(dci->antenna_ports.val-2)):dci->antenna_ports.val; //TBC + } + + if (rank == 2){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?((dci->antenna_ports.val > 2)?3:2):1; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_17[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_17[dci->antenna_ports.val][2]; + } + + if (rank == 3){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = (dci->antenna_ports.val > 0)?3:2; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_18[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_18[dci->antenna_ports.val][2]; + //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_18[dci->antenna_ports.val][3]; + } + + if (rank == 4){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = dci->antenna_ports.val + 2; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = 0; + //pusch_config_pdu->dmrs_ports[1] = 1; + //pusch_config_pdu->dmrs_ports[2] = 2; + //pusch_config_pdu->dmrs_ports[3] = 3; + } + } + + if ((pusch_config_dedicated->transform_precoder == transform_precoder_disabled) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.dmrs_type == 2) && + (pusch_config_dedicated->dmrs_ul_for_pusch_mapping_type_a.max_length == 2)) { // tables 7.3.1.1.2-20/21/22/23 + + if (rank == 1){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_20[dci->antenna_ports.val][0]; //TBC + pusch_config_pdu->dmrs_ports = table_7_3_1_1_2_20[dci->antenna_ports.val][1]; //TBC + //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_20[dci->antenna_ports.val][2]; //FIXME + } + + if (rank == 2){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_21[dci->antenna_ports.val][0]; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_21[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_21[dci->antenna_ports.val][2]; + //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_21[dci->antenna_ports.val][3]; //FIXME + } + + if (rank == 3){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_22[dci->antenna_ports.val][0]; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_22[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_22[dci->antenna_ports.val][2]; + //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_22[dci->antenna_ports.val][3]; + //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_22[dci->antenna_ports.val][4]; //FIXME + } + + if (rank == 4){ + pusch_config_pdu->num_dmrs_cdm_grps_no_data = table_7_3_1_1_2_23[dci->antenna_ports.val][0]; //TBC + pusch_config_pdu->dmrs_ports = 0; //FIXME + //pusch_config_pdu->dmrs_ports[0] = table_7_3_1_1_2_23[dci->antenna_ports.val][1]; + //pusch_config_pdu->dmrs_ports[1] = table_7_3_1_1_2_23[dci->antenna_ports.val][2]; + //pusch_config_pdu->dmrs_ports[2] = table_7_3_1_1_2_23[dci->antenna_ports.val][3]; + //pusch_config_pdu->dmrs_ports[3] = table_7_3_1_1_2_23[dci->antenna_ports.val][4]; + //pusch_config_pdu->n_front_load_symb = table_7_3_1_1_2_23[dci->antenna_ports.val][5]; //FIXME + } + } +} + +// Configuration of Msg3 PDU according to clauses: +// - 8.3 of 3GPP TS 38.213 version 16.3.0 Release 16 +// - 6.1.2.2 of TS 38.214 +// - 6.1.3 of TS 38.214 +// - 6.2.2 of TS 38.214 +// - 6.1.4.2 of TS 38.214 +// - 6.4.1.1.1 of TS 38.211 +// - 6.3.1.7 of 38.211 +int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, + dci_pdu_rel15_t *dci, + RAR_grant_t *rar_grant, + uint16_t rnti, + uint8_t *dci_format){ + + int f_alloc; + int mask; + int StartSymbolIndex; + int NrOfSymbols; + uint8_t nb_dmrs_re_per_rb; + + uint16_t l_prime_mask = 1; + uint16_t number_dmrs_symbols = 0; + int N_PRB_oh = 0; + + NR_ServingCellConfigCommon_t *scc = mac->scc; + int rnti_type = get_rnti_type(mac, rnti); + + // Common configuration + pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; + pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_config_pdu->nrOfLayers = 1; + pusch_config_pdu->rnti = rnti; + + if (rar_grant) { + + // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0 + + NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; + NR_BWP_UplinkDedicated_t *ibwp = mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; + NR_PUSCH_Config_t *pusch_Config = ibwp->pusch_Config->choice.setup; + int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[rar_grant->Msg3_t_alloc]->startSymbolAndLength; + + // active BWP start + int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + // initial BWP start + int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + // BWP start selection according to 8.3 of TS 38.213 + pusch_config_pdu->bwp_size = ibwp_size; + if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) + pusch_config_pdu->bwp_start = abwp_start; + else + pusch_config_pdu->bwp_start = ibwp_start; + + //// Resource assignment from RAR + // Frequency domain allocation according to 8.3 of TS 38.213 + if (ibwp_size < 180) + mask = (1 << ((int) ceil(log2((ibwp_size*(ibwp_size+1))>>1)))) - 1; + else + mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1; + + f_alloc = rar_grant->Msg3_f_alloc & mask; + if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc) < 0) + return -1; + + // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211) + pusch_config_pdu->rb_start += ibwp_start - abwp_start; + + // Time domain allocation + SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); + pusch_config_pdu->start_symbol_index = StartSymbolIndex; + pusch_config_pdu->nr_of_symbols = NrOfSymbols; + + #ifdef DEBUG_MSG3 + LOG_D(MAC, "In %s BWP assignment (BWP (start %d, size %d) \n", __FUNCTION__, pusch_config_pdu->bwp_start, pusch_config_pdu->bwp_size); + #endif + + // MCS + pusch_config_pdu->mcs_index = rar_grant->mcs; + // Frequency hopping + pusch_config_pdu->frequency_hopping = rar_grant->freq_hopping; + + // DM-RS configuration according to 6.2.2 UE DM-RS transmission procedure in 38.214 + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + pusch_config_pdu->dmrs_ports = 1; + + // DMRS sequence initialization [TS 38.211, sec 6.4.1.1.1]. + // Should match what is sent in DCI 0_1, otherwise set to 0. + pusch_config_pdu->scid = 0; + + // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 + pusch_config_pdu->transform_precoding = get_transformPrecoding(scc, pusch_Config, NULL, NULL, NR_RNTI_RA, 0); // TBR fix rnti and take out + + // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 + pusch_config_pdu->resource_alloc = pusch_Config->resourceAllocation; + + //// Completing PUSCH PDU + pusch_config_pdu->mcs_table = 0; + pusch_config_pdu->cyclic_prefix = 0; + pusch_config_pdu->data_scrambling_id = *scc->physCellId; + pusch_config_pdu->ul_dmrs_scrambling_id = *scc->physCellId; + pusch_config_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_config_pdu->vrb_to_prb_mapping = 0; + pusch_config_pdu->uplink_frequency_shift_7p5khz = 0; + //Optional Data only included if indicated in pduBitmap + pusch_config_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213 + pusch_config_pdu->pusch_data.harq_process_id = 0; + pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data + pusch_config_pdu->pusch_data.num_cb = 0; + + } else if (dci) { + + int target_ss; + uint8_t ptrs_time_density; + uint8_t ptrs_freq_density; + nfapi_nr_ue_ptrs_ports_t ptrs_ports_list; + uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + fapi_nr_pusch_config_dedicated_t *pusch_config_dedicated = &mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated; + NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup; + + // These should come from RRC config!!! + uint8_t ptrs_mcs1 = 2; + uint8_t ptrs_mcs2 = 4; + uint8_t ptrs_mcs3 = 10; + uint16_t n_rb0 = 25; + uint16_t n_rb1 = 75; + + // Basic sanity check for MCS value to check for a false or erroneous DCI + if (dci->mcs > 28) { + LOG_W(MAC, "MCS value %d out of bounds! Possibly due to false DCI. Ignoring DCI!\n", dci->mcs); + return -1; + } + + /* Transform precoding */ + if (rnti_type != NR_RNTI_CS || (rnti_type == NR_RNTI_CS && dci->ndi == 1)) { + pusch_config_pdu->transform_precoding = get_transformPrecoding(scc, pusch_Config, NULL, dci_format, rnti_type, 0); + } + + /*DCI format-related configuration*/ + if (*dci_format == NR_UL_DCI_FORMAT_0_0) { + + target_ss = NR_SearchSpace__searchSpaceType_PR_common; + + } else if (*dci_format == NR_UL_DCI_FORMAT_0_1) { + + /* BANDWIDTH_PART_IND */ + if (dci->bwp_indicator.val != 1) { + LOG_W(MAC, "bwp_indicator != 1! Possibly due to false DCI. Ignoring DCI!\n"); + return -1; + } + config_bwp_ue(mac, &dci->bwp_indicator.val, dci_format); + target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + ul_layers_config(mac, pusch_config_pdu, dci); + ul_ports_config(mac, pusch_config_pdu, dci); + + } else { + + LOG_E(MAC, "In %s: UL grant from DCI format %d is not handled...\n", __FUNCTION__, *dci_format); + return -1; + + } + + /* TRANSFORM PRECODING ------------------------------------------------------------------------------------------*/ + + if (pusch_config_pdu->transform_precoding == transform_precoder_enabled) { + + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; + + NR_DMRS_UplinkConfig_t *NR_DMRS_ulconfig = NULL; + if(pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA != NULL) + NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; + else + NR_DMRS_ulconfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + + uint32_t n_RS_Id = 0; + if (NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) + n_RS_Id = *NR_DMRS_ulconfig->transformPrecodingEnabled->nPUSCH_Identity; + else + n_RS_Id = *mac->scc->physCellId; + + // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled + pusch_config_pdu->dfts_ofdm.low_papr_group_number = n_RS_Id % 30; + + // V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled + if ((NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) && + (NR_DMRS_ulconfig->transformPrecodingEnabled->sequenceHopping == NULL)) + pusch_config_pdu->dfts_ofdm.low_papr_sequence_number = 0; + else + AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); + + LOG_D(MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d \n", pusch_config_pdu->num_dmrs_cdm_grps_no_data, + pusch_config_pdu->dfts_ofdm.low_papr_group_number); + } + + /* TRANSFORM PRECODING --------------------------------------------------------------------------------------------------------*/ + + /* IDENTIFIER_DCI_FORMATS */ + /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ + if (nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, n_RB_ULBWP, 0, dci->frequency_domain_assignment.val) < 0){ + return -1; + } + /* TIME_DOM_RESOURCE_ASSIGNMENT */ + if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val) < 0) { + return -1; + } + + /* FREQ_HOPPING_FLAG */ + if ((pusch_config_dedicated->resource_allocation != 0) && (pusch_config_dedicated->frequency_hopping !=0)){ + pusch_config_pdu->frequency_hopping = dci->frequency_hopping_flag.val; + } + + /* MCS */ + pusch_config_pdu->mcs_index = dci->mcs; + + /* MCS TABLE */ + if (pusch_config_pdu->transform_precoding == transform_precoder_disabled) { + pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0, *dci_format, rnti_type, target_ss, false); + } else { + pusch_config_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1, *dci_format, rnti_type, target_ss, false); + } + + /* NDI */ + pusch_config_pdu->pusch_data.new_data_indicator = dci->ndi; + /* RV */ + pusch_config_pdu->pusch_data.rv_index = dci->rv; + /* HARQ_PROCESS_NUMBER */ + pusch_config_pdu->pusch_data.harq_process_id = dci->harq_pid; + /* TPC_PUSCH */ + // according to TS 38.213 Table Table 7.1.1-1 + if (dci->tpc == 0) { + pusch_config_pdu->absolute_delta_PUSCH = -4; + } + if (dci->tpc == 1) { + pusch_config_pdu->absolute_delta_PUSCH = -1; + } + if (dci->tpc == 2) { + pusch_config_pdu->absolute_delta_PUSCH = 1; + } + if (dci->tpc == 3) { + pusch_config_pdu->absolute_delta_PUSCH = 4; + } + + ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); + ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_config_pdu->rb_size); + // PTRS ports configuration + // TbD: ptrs_dmrs_port and ptrs_port_index are not initialised! + ptrs_ports_list.ptrs_re_offset = 0; + + /* DMRS */ + l_prime_mask = get_l_prime(pusch_config_pdu->nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); + if (pusch_config_pdu->transform_precoding == transform_precoder_disabled) + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; + + // Num PRB Overhead from PUSCH-ServingCellConfig + if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL) { + N_PRB_oh = 0; + } else { + N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead; + } + + /* PTRS */ + pusch_config_pdu->pusch_ptrs.ptrs_time_density = ptrs_time_density; + pusch_config_pdu->pusch_ptrs.ptrs_freq_density = ptrs_freq_density; + pusch_config_pdu->pusch_ptrs.ptrs_ports_list = &ptrs_ports_list; + + if (1 << pusch_config_pdu->pusch_ptrs.ptrs_time_density >= pusch_config_pdu->nr_of_symbols) { + pusch_config_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + } + + } + + LOG_D(MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) for RNTI type %s \n", + __FUNCTION__, + pusch_config_pdu->rb_start, + pusch_config_pdu->rb_size, + pusch_config_pdu->start_symbol_index, + pusch_config_pdu->nr_of_symbols, + rnti_types[rnti_type]); + + pusch_config_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_config_pdu->start_symbol_index;; + pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); + pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); + + if (pusch_config_pdu->target_code_rate == 0 || pusch_config_pdu->qam_mod_order == 0) { + LOG_W(MAC, "In %s: Invalid code rate or Mod order, likely due to unexpected UL DCI. Ignoring DCI! \n", __FUNCTION__); + return -1; + } + + get_num_re_dmrs(pusch_config_pdu, &nb_dmrs_re_per_rb, &number_dmrs_symbols); + + // Compute TBS + pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order, + pusch_config_pdu->target_code_rate, + pusch_config_pdu->rb_size, + pusch_config_pdu->nr_of_symbols, + nb_dmrs_re_per_rb*number_dmrs_symbols, + N_PRB_oh, + 0, // TBR to verify tb scaling + pusch_config_pdu->nrOfLayers)/8; + + return 0; + +} + +// Performs : +// 1. TODO: Call RRC for link status return to PHY +// 2. TODO: Perform SR/BSR procedures for scheduling feedback +// 3. TODO: Perform PHR procedures +NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_indication_t *ul_info){ + + uint32_t search_space_mask = 0; + + if (dl_info){ + + module_id_t mod_id = dl_info->module_id; + uint32_t gNB_index = dl_info->gNB_index; + int cc_id = dl_info->cc_id; + frame_t rx_frame = dl_info->frame; + slot_t rx_slot = dl_info->slot; + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + + fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; + nr_scheduled_response_t scheduled_response; + nr_dcireq_t dcireq; + + // check type0 from 38.213 13 if we have no CellGroupConfig + // TODO: implementation to be completed + if (mac->scg == NULL) { + + if(dl_info->ssb_index != -1){ + + if(mac->type0_pdcch_ss_mux_pattern == 1){ + // 38.213 chapter 13 + if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_0) && !(rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + if((mac->type0_pdcch_ss_sfn_c == SFN_C_MOD_2_EQ_1) && (rx_frame & 0x1) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + } + if(mac->type0_pdcch_ss_mux_pattern == 2){ + // 38.213 Table 13-13, 13-14 + if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + } + if(mac->type0_pdcch_ss_mux_pattern == 3){ + // 38.213 Table 13-15 + if((rx_frame == get_ssb_frame(rx_frame)) && (rx_slot == mac->type0_pdcch_ss_n_c)){ + search_space_mask = search_space_mask | type0_pdcch; + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_dci_config.coreset.duration; + } + } + } // ssb_index != -1 + + // Type0 PDCCH search space + if((search_space_mask & type0_pdcch) || ( mac->type0_pdcch_consecutive_slots != 0 )){ + mac->type0_pdcch_consecutive_slots = mac->type0_pdcch_consecutive_slots - 1; + + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15 = mac->type0_pdcch_dci_config; + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; + + /* + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti = 0xaaaa; // to be set + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = 106; // to be set + + LOG_I(MAC,"nr_ue_scheduler Type0 PDCCH with rnti %x, BWP %d\n", + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.rnti, + dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP); + */ + dl_config->number_pdus = dl_config->number_pdus + 1; + + fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + mac->if_module->scheduled_response(&scheduled_response); + } + } else { // we have an scg + + dcireq.module_id = mod_id; + dcireq.gNB_index = gNB_index; + dcireq.cc_id = cc_id; + dcireq.frame = rx_frame; + dcireq.slot = rx_slot; + dcireq.dl_config_req.number_pdus = 0; + nr_ue_dcireq(&dcireq); //to be replaced with function pointer later + + fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ + mac->if_module->scheduled_response(&scheduled_response); + } + + /* + if(search_space_mask & type0a_pdcch){ + } + + if(search_space_mask & type1_pdcch){ + } + + if(search_space_mask & type2_pdcch){ + } + + if(search_space_mask & type3_pdcch){ + } + */ + } + } else if (ul_info) { + + int cc_id = ul_info->cc_id; + frame_t rx_frame = ul_info->frame_rx; + slot_t rx_slot = ul_info->slot_rx; + frame_t frame_tx = ul_info->frame_tx; + slot_t slot_tx = ul_info->slot_tx; + module_id_t mod_id = ul_info->module_id; + uint8_t access_mode = SCHEDULED_ACCESS; + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + RA_config_t *ra = &mac->ra; + + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); + + // Schedule ULSCH only if the current frame and slot match those in ul_config_req + // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) + if ((ul_info->slot_tx == ul_config->slot && ul_info->frame_tx == ul_config->sfn) && ul_config->number_pdus > 0){ + + LOG_D(MAC, "In %s:[%d.%d]: number of UL PDUs: %d with UL transmission in [%d.%d]\n", __FUNCTION__, frame_tx, slot_tx, ul_config->number_pdus, ul_config->sfn, ul_config->slot); + + uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; + uint8_t data_existing = 0; + nr_scheduled_response_t scheduled_response; + fapi_nr_tx_request_t tx_req; + + for (int j = 0; j < ul_config->number_pdus; j++) { + + fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = &ul_config->ul_config_list[j]; + + if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { + + uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; + + // Push data from MAC to PHY only when NDI toggles + if (IS_SOFTMODEM_NOS1 && (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator)){ + // Getting IP traffic to be transmitted + data_existing = nr_ue_get_sdu(mod_id, + cc_id, + frame_tx, + slot_tx, + 0, + ulsch_input_buffer, + TBS_bytes, + &access_mode); + } + + mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator; + //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity + if (!IS_SOFTMODEM_NOS1 || !data_existing) { + //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid + //and block this traffic from being forwarded to the upper layers at the gNB + LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes); + + //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) + //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should + //have a valid LCID (nr_process_mac_pdu function) + ulsch_input_buffer[0] = 0x31; + + for (int i = 1; i < TBS_bytes; i++) { + ulsch_input_buffer[i] = (unsigned char) rand(); + //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } + } + + #ifdef DEBUG_MAC_PDU + LOG_D(PHY, "Is data existing ?: %d \n", data_existing); + LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes); + for (i = 0; i < TBS_bytes; i++) { + printf("%02x", ulsch_input_buffer[i]); + } + printf("\n"); + #endif + + // Config UL TX PDU + tx_req.slot = slot_tx; + tx_req.sfn = frame_tx; + tx_req.number_of_pdus++; + tx_req.tx_request_body[0].pdu_length = TBS_bytes; + tx_req.tx_request_body[0].pdu_index = j; + tx_req.tx_request_body[0].pdu = ulsch_input_buffer; + + if (ra->ra_state != RA_SUCCEEDED && !ra->cfra){ + nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index); + } + + } + } + + fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, mod_id, cc_id, rx_frame, rx_slot, ul_info->thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ + mac->if_module->scheduled_response(&scheduled_response); + } + } + } + + return UE_CONNECTION_OK; + +} + +// PUSCH scheduler: +// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, +// - where K2 is the offset between the slot in which UL DCI is received and the slot +// - in which ULSCH should be scheduled. K2 is configured in RRC configuration. +// PUSCH Msg3 scheduler: +// - scheduled by RAR UL grant according to 8.3 of TS 38.213 +// Note: Msg3 tx in the uplink symbols of mixed slot +int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, + uint8_t is_Msg3, + frame_t current_frame, + int current_slot, + frame_t *frame_tx, + int *slot_tx, + uint8_t tda_id){ + + int delta = 0; + NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; + // Get the numerology to calculate the Tx frame and slot + int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 + // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon + uint8_t k2; + + if (is_Msg3) { + k2 = *pusch_TimeDomainAllocationList->list.array[tda_id]->k2; + + switch (mu) { + case 0: + delta = 2; + break; + case 1: + delta = 3; + break; + case 2: + delta = 4; + break; + case 3: + delta = 6; + break; + } + + *slot_tx = (current_slot + k2 + delta) % nr_slots_per_frame[mu]; + if (current_slot + k2 + delta > nr_slots_per_frame[mu]){ + *frame_tx = (current_frame + 1) % 1024; + } else { + *frame_tx = current_frame; + } + + } else { + + // Get slot offset K2 which will be used to calculate TX slot + k2 = get_k2(mac, tda_id); + if (k2 < 0) { // This can happen when a false DCI is received + return -1; + } + + // Calculate TX slot and frame + *slot_tx = (current_slot + k2) % nr_slots_per_frame[mu]; + *frame_tx = ((current_slot + k2) > nr_slots_per_frame[mu]) ? (current_frame + 1) % 1024 : current_frame; + + } + + LOG_D(MAC, "In %s: currently at [%d.%d] UL transmission in [%d.%d] (k2 %d delta %d)\n", __FUNCTION__, current_frame, current_slot, *frame_tx, *slot_tx, k2, delta); + + return 0; + +} + +// Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config +static void build_ro_list(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired) { + + int x,y; // PRACH Configuration Index table variables used to compute the valid frame numbers + int y2; // PRACH Configuration Index table additional variable used to compute the valid frame numbers + uint8_t slot_shift_for_map; + uint8_t map_shift; + boolean_t even_slot_invalid; + int64_t s_map; + uint8_t prach_conf_start_symbol; // Starting symbol of the PRACH occasions in the PRACH slot + uint8_t N_t_slot; // Number of PRACH occasions in a 14-symbols PRACH slot + uint8_t N_dur; // Duration of a PRACH occasion (nb of symbols) + uint8_t frame; // Maximum is NB_FRAMES_IN_MAX_ASSOCIATION_PATTERN_PERIOD + uint8_t slot; // Maximum is the number of slots in a frame @ SCS 240kHz + uint16_t format = 0xffff; + uint8_t format2 = 0xff; + int nb_fdm; + + uint8_t config_index, mu; + uint32_t pointa; + int msg1_FDM; + + uint8_t prach_conf_period_idx; + uint8_t nb_of_frames_per_prach_conf_period; + uint8_t prach_conf_period_frame_idx; + int64_t *prach_config_info_p; + + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + + config_index = rach_ConfigGeneric->prach_ConfigurationIndex; + + if (setup->msg1_SubcarrierSpacing) + mu = *setup->msg1_SubcarrierSpacing; + else + mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + pointa = frequencyInfoDL->absoluteFrequencyPointA; + msg1_FDM = rach_ConfigGeneric->msg1_FDM; + + switch (msg1_FDM){ + case 0: + case 1: + case 2: + case 3: + nb_fdm = 1 << msg1_FDM; + break; + default: + AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", msg1_FDM); + } + + // Create the PRACH occasions map + // ============================== + // WIP: For now assume no rejected PRACH occasions because of conflict with SSB or TDD_UL_DL_ConfigurationCommon schedule + + // Identify the proper PRACH Configuration Index table according to the operating frequency + LOG_D(MAC,"Pointa %u, mu = %u, PRACH config index = %u, unpaired = %u\n", pointa, mu, config_index, unpaired); + + prach_config_info_p = get_prach_config_info(pointa, config_index, unpaired); + + if (pointa > 2016666) { //FR2 + + x = prach_config_info_p[2]; + y = prach_config_info_p[3]; + y2 = prach_config_info_p[4]; + + s_map = prach_config_info_p[5]; + + prach_conf_start_symbol = prach_config_info_p[6]; + N_t_slot = prach_config_info_p[8]; + N_dur = prach_config_info_p[9]; + if (prach_config_info_p[1] != -1) + format2 = (uint8_t) prach_config_info_p[1]; + format = ((uint8_t) prach_config_info_p[0]) | (format2<<8); + + slot_shift_for_map = mu-2; + if ( (mu == 3) && (prach_config_info_p[7] == 1) ) + even_slot_invalid = true; + else + even_slot_invalid = false; + } + else { // FR1 + x = prach_config_info_p[2]; + y = prach_config_info_p[3]; + y2 = y; + + s_map = prach_config_info_p[4]; + + prach_conf_start_symbol = prach_config_info_p[5]; + N_t_slot = prach_config_info_p[7]; + N_dur = prach_config_info_p[8]; + if (prach_config_info_p[1] != -1) + format2 = (uint8_t) prach_config_info_p[1]; + format = ((uint8_t) prach_config_info_p[0]) | (format2<<8); + + slot_shift_for_map = mu; + if ( (mu == 1) && (prach_config_info_p[6] <= 1) ) + // no prach in even slots @ 30kHz for 1 prach per subframe + even_slot_invalid = true; + else + even_slot_invalid = false; + } // FR2 / FR1 + + prach_assoc_pattern.nb_of_prach_conf_period_in_max_period = MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD / x; + nb_of_frames_per_prach_conf_period = x; + + LOG_D(MAC,"nb_of_prach_conf_period_in_max_period %d\n", prach_assoc_pattern.nb_of_prach_conf_period_in_max_period); + + // Fill in the PRACH occasions table for every slot in every frame in every PRACH configuration periods in the maximum association pattern period + // ---------------------------------------------------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------------------------------------------- + // For every PRACH configuration periods + // ------------------------------------- + for (prach_conf_period_idx=0; prach_conf_period_idx> slot_shift_for_map; // in PRACH configuration index table slots are numbered wrt 60kHz + if ( (s_map>>map_shift)&0x01 ) { + // Valid slot + + // Additionally, for 30kHz/120kHz, we must check for the n_RA_Slot param also + if ( even_slot_invalid && (slot%2 == 0) ) + continue; // no prach in even slots @ 30kHz/120kHz for 1 prach per 60khz slot/subframe + + // We're good: valid frame and valid slot + // Compute all the PRACH occasions in the slot + + uint8_t n_prach_occ_in_time; + uint8_t n_prach_occ_in_freq; + + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time = N_t_slot; + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq = nb_fdm; + + for (n_prach_occ_in_time=0; n_prach_occ_in_timestart_symbol = start_symbol; + prach_occasion_p->fdm = n_prach_occ_in_freq; + prach_occasion_p->frame = frame; + prach_occasion_p->slot = slot; + prach_occasion_p->format = format; + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion++; + + LOG_D(MAC,"Adding a PRACH occasion: frame %u, slot-symbol %d-%d, occ_in_time-occ_in-freq %d-%d, nb ROs in conf period %d, for this slot: RO# in time %d, RO# in freq %d\n", + frame, slot, start_symbol, n_prach_occ_in_time, n_prach_occ_in_freq, prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].nb_of_prach_occasion, + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_time, + prach_assoc_pattern.prach_conf_period_list[prach_conf_period_idx].prach_occasion_slot_map[prach_conf_period_frame_idx][slot].nb_of_prach_occasion_in_freq); + } // For every freq in the slot + } // For every time occasions in the slot + } // Valid slot? + } // For every slots in a frame + } // Valid frame? + } // For every frames in a prach configuration period + } // For every prach configuration periods in the maximum association pattern period (160ms) +} + +// Build the list of all the valid/transmitted SSBs according to the config +static void build_ssb_list(NR_ServingCellConfigCommon_t *scc) { + + // Create the list of transmitted SSBs + // =================================== + BIT_STRING_t *ssb_bitmap; + uint64_t ssb_positionsInBurst; + uint8_t ssb_idx = 0; + + switch (scc->ssb_PositionsInBurst->present) { + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: + ssb_bitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; + + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); + LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); + + for (uint8_t bit_nb=3; bit_nb<=3; bit_nb--) { + // If SSB is transmitted + if ((ssb_positionsInBurst>>bit_nb) & 0x01) { + ssb_list.nb_tx_ssb++; + ssb_list.tx_ssb[ssb_idx].transmitted = true; + LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx); + } + ssb_idx++; + } + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: + ssb_bitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap; + + ssb_positionsInBurst = BIT_STRING_to_uint8(ssb_bitmap); + LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); + + for (uint8_t bit_nb=7; bit_nb<=7; bit_nb--) { + // If SSB is transmitted + if ((ssb_positionsInBurst>>bit_nb) & 0x01) { + ssb_list.nb_tx_ssb++; + ssb_list.tx_ssb[ssb_idx].transmitted = true; + LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx); + } + ssb_idx++; + } + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + ssb_bitmap = &scc->ssb_PositionsInBurst->choice.longBitmap; + + ssb_positionsInBurst = BIT_STRING_to_uint64(ssb_bitmap); + LOG_D(MAC,"SSB config: SSB_positions_in_burst 0x%lx\n", ssb_positionsInBurst); + + for (uint8_t bit_nb=63; bit_nb<=63; bit_nb--) { + // If SSB is transmitted + if ((ssb_positionsInBurst>>bit_nb) & 0x01) { + ssb_list.nb_tx_ssb++; + ssb_list.tx_ssb[ssb_idx].transmitted = true; + LOG_D(MAC,"SSB idx %d transmitted\n", ssb_idx); + } + ssb_idx++; + } + break; + default: + AssertFatal(false,"ssb_PositionsInBurst not present\n"); + break; + } +} + +// Map the transmitted SSBs to the ROs and create the association pattern according to the config +static void map_ssb_to_ro(NR_ServingCellConfigCommon_t *scc) { + + // Map SSBs to PRACH occasions + // =========================== + // WIP: Assumption: No PRACH occasion is rejected because of a conflict with SSBs or TDD_UL_DL_ConfigurationCommon schedule + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + + boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB + uint16_t required_nb_of_prach_occasion; // Nb of RACH occasions required to map all the SSBs + uint8_t required_nb_of_prach_conf_period; // Nb of PRACH configuration periods required to map all the SSBs + + // Determine the SSB to RACH mapping ratio + // ======================================= + switch (ssb_perRACH_config){ + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 8; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 4; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf: + multiple_ssb_per_ro = false; + ssb_rach_ratio = 2; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 1; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 2; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 4; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 8; + break; + case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen: + multiple_ssb_per_ro = true; + ssb_rach_ratio = 16; + break; + default: + AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config); + break; + } + LOG_D(MAC,"SSB rach ratio %d, Multiple SSB per RO %d\n", ssb_rach_ratio, multiple_ssb_per_ro); + + // Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period + // ============================================================================================================== + // WIP: Assumption for now is that all the PRACH configuration periods within a maximum association pattern period have the same number of PRACH occasions + // (No PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule) + // There is only one possible association period which can contain up to 16 PRACH configuration periods + LOG_D(MAC,"Evaluate the number of PRACH configuration periods required to map all the SSBs and set the association period\n"); + if (true == multiple_ssb_per_ro) { + required_nb_of_prach_occasion = ((ssb_list.nb_tx_ssb-1) + ssb_rach_ratio) / ssb_rach_ratio; + } + else { + required_nb_of_prach_occasion = ssb_list.nb_tx_ssb * ssb_rach_ratio; + } + + required_nb_of_prach_conf_period = ((required_nb_of_prach_occasion-1) + prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion) / prach_assoc_pattern.prach_conf_period_list[0].nb_of_prach_occasion; + + if (required_nb_of_prach_conf_period == 1) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 1; + } + else if (required_nb_of_prach_conf_period == 2) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 2; + } + else if (required_nb_of_prach_conf_period <= 4) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 4; + } + else if (required_nb_of_prach_conf_period <= 8) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 8; + } + else if (required_nb_of_prach_conf_period <= 16) { + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period = 16; + } + else { + AssertFatal(1 == 0, "Invalid number of PRACH config periods within an association period %d\n", required_nb_of_prach_conf_period); + } + + prach_assoc_pattern.nb_of_assoc_period = 1; // WIP: only one possible association period + prach_assoc_pattern.prach_association_period_list[0].nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period * prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + prach_assoc_pattern.nb_of_frame = prach_assoc_pattern.prach_association_period_list[0].nb_of_frame; + + LOG_D(MAC,"Assoc period %d, Nb of frames in assoc period %d\n", + prach_assoc_pattern.prach_association_period_list[0].nb_of_prach_conf_period, + prach_assoc_pattern.prach_association_period_list[0].nb_of_frame); + + // Proceed to the SSB to RO mapping + // ================================ + uint8_t association_period_idx; // Association period index within the association pattern + uint8_t ssb_idx = 0; + uint8_t prach_configuration_period_idx; // PRACH Configuration period index within the association pattern + prach_conf_period_t *prach_conf_period_p; + + // Map all the association periods within the association pattern period + LOG_D(MAC,"Proceed to the SSB to RO mapping\n"); + for (association_period_idx=0; association_period_idxnb_of_frame; frame++) { + for (slot=0; slotnb_of_slot; slot++) { + for (ro_in_time=0; ro_in_timeprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { + for (ro_in_freq=0; ro_in_freqprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; + + // Go through the list of transmitted SSBs and map the required amount of SSBs to this RO + // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO + // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule + for (; ssb_idxmapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx; + ro_p->nb_mapped_ssb++; + ssb_list.tx_ssb[ssb_idx].mapped_ro[ssb_list.tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; + ssb_list.tx_ssb[ssb_idx].nb_mapped_ro++; + AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + + LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); + LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + + // If all the required SSBs are mapped to this RO, exit the loop of SSBs + if (ro_p->nb_mapped_ssb == ssb_rach_ratio) { + ssb_idx++; + break; + } + } // if ssb_idx is transmitted + } // for ssb_idx + + // Exit the loop of ROs if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for ro_in_freq + + // Exit the loop of ROs if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for ro_in_time + + // Exit the loop of slots if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for slot + + // Exit the loop frames if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for frame + + // Exit the loop of PRACH configurations if there is no more SSB to map + if (MAX_NB_SSB == ssb_idx) break; + } // for n_prach_conf + + // WIP: note that there is no re-mapping of the SSBs within the association period since there is no invalid ROs in the PRACH config periods that would create this situation + + } // if multiple_ssbs_per_ro + + else { + // -------------------- + // -------------------- + // Multiple ROs per SSB + // -------------------- + // -------------------- + + n_prach_conf = 0; + + // Go through the list of transmitted SSBs + for (ssb_idx=0; ssb_idxnb_of_frame; frame++) { + for (; slotnb_of_slot; slot++) { + for (; ro_in_timeprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_time; ro_in_time++) { + for (; ro_in_freqprach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *ro_p = &prach_conf_period_p->prach_occasion_slot_map[frame][slot].prach_occasion[ro_in_time][ro_in_freq]; + + ro_p->mapped_ssb_idx[0] = ssb_idx; + ro_p->nb_mapped_ssb = 1; + ssb_list.tx_ssb[ssb_idx].mapped_ro[ssb_list.tx_ssb[ssb_idx].nb_mapped_ro] = ro_p; + ssb_list.tx_ssb[ssb_idx].nb_mapped_ro++; + AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > ssb_list.tx_ssb[ssb_idx].nb_mapped_ro,"Too many mapped ROs (%d) to a single SSB\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro); + nb_mapped_ro_in_association_period++; + + LOG_D(MAC,"Mapped ssb_idx %u to RO slot-symbol %u-%u, %u-%u-%u/%u\n", ssb_idx, ro_p->slot, ro_p->start_symbol, slot, ro_in_time, ro_in_freq, prach_conf_period_p->prach_occasion_slot_map[frame][slot].nb_of_prach_occasion_in_freq); + LOG_D(MAC,"Nb mapped ROs for this ssb idx: in the association period only %u / total %u\n", ssb_list.tx_ssb[ssb_idx].nb_mapped_ro, nb_mapped_ro_in_association_period); + + // Exit the loop if this SSB has been mapped to all the required ROs + // WIP: Assuming that ssb_rach_ratio equals the maximum nb of times a given ssb_idx is mapped within an association period: + // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + ro_in_freq++; + break; + } + } // for ro_in_freq + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else ro_in_freq = 0; // else go to the next time symbol in that slot and reset the freq index + } // for ro_in_time + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else ro_in_time = 0; // else go to the next slot in that PRACH config period and reset the symbol index + } // for slot + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else slot = 0; // else go to the next frame in that PRACH config period and reset the slot index + } // for frame + + // Exit the loop if this SSB has been mapped to all the required ROs + if (nb_mapped_ro_in_association_period == ssb_rach_ratio) { + break; + } + else frame = 0; // else go to the next PRACH config period in that association period and reset the frame index + } // for n_prach_conf + + } // if ssb_idx is transmitted + } // for ssb_idx + } // else if multiple_ssbs_per_ro + + } // for association_period_index +} + +// Returns a RACH occasion if any matches the SSB idx, the frame and the slot +static int get_nr_prach_info_from_ssb_index(uint8_t ssb_idx, + int frame, + int slot, + prach_occasion_info_t **prach_occasion_info_pp) { + + ssb_info_t *ssb_info_p; + prach_occasion_slot_t *prach_occasion_slot_p = NULL; + + *prach_occasion_info_pp = NULL; + + // Search for a matching RO slot in the SSB_to_RO map + // A valid RO slot will match: + // - ssb_idx mapped to one of the ROs in that RO slot + // - exact slot number + // - frame offset + ssb_info_p = &ssb_list.tx_ssb[ssb_idx]; + for (uint8_t n_mapped_ro=0; n_mapped_ronb_mapped_ro; n_mapped_ro++) { + if ((slot == ssb_info_p->mapped_ro[n_mapped_ro]->slot) && + (ssb_info_p->mapped_ro[n_mapped_ro]->frame == (frame % prach_assoc_pattern.nb_of_frame))) { + + uint8_t prach_config_period_nb = ssb_info_p->mapped_ro[n_mapped_ro]->frame / prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + uint8_t frame_nb_in_prach_config_period = ssb_info_p->mapped_ro[n_mapped_ro]->frame % prach_assoc_pattern.prach_conf_period_list[0].nb_of_frame; + prach_occasion_slot_p = &prach_assoc_pattern.prach_conf_period_list[prach_config_period_nb].prach_occasion_slot_map[frame_nb_in_prach_config_period][slot]; + } + } + + // If there is a matching RO slot in the SSB_to_RO map + if (NULL != prach_occasion_slot_p) + { + // A random RO mapped to the SSB index should be selected in the slot + + // First count the number of times the SSB index is found in that RO + uint8_t nb_mapped_ssb = 0; + + for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { + for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; + + for (uint8_t ssb_nb=0; ssb_nbnb_mapped_ssb; ssb_nb++) { + if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { + nb_mapped_ssb++; + } + } + } + } + + // Choose a random SSB nb + uint8_t random_ssb_nb = 0; + + random_ssb_nb = ((taus()) % nb_mapped_ssb); + + // Select the RO according to the chosen random SSB nb + nb_mapped_ssb=0; + for (int ro_in_time=0; ro_in_time < prach_occasion_slot_p->nb_of_prach_occasion_in_time; ro_in_time++) { + for (int ro_in_freq=0; ro_in_freq < prach_occasion_slot_p->nb_of_prach_occasion_in_freq; ro_in_freq++) { + prach_occasion_info_t *prach_occasion_info_p = &prach_occasion_slot_p->prach_occasion[ro_in_time][ro_in_freq]; + + for (uint8_t ssb_nb=0; ssb_nbnb_mapped_ssb; ssb_nb++) { + if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb] == ssb_idx) { + if (nb_mapped_ssb == random_ssb_nb) { + *prach_occasion_info_pp = prach_occasion_info_p; + return 1; + } + else { + nb_mapped_ssb++; + } + } + } + } + } + } + + return 0; +} + +// Build the SSB to RO mapping upon RRC configuration update +void build_ssb_to_ro_map(NR_ServingCellConfigCommon_t *scc, uint8_t unpaired){ + + // Clear all the lists and maps + memset(&prach_assoc_pattern, 0, sizeof(prach_association_pattern_t)); + memset(&ssb_list, 0, sizeof(ssb_list_info_t)); + + // Build the list of all the valid RACH occasions in the maximum association pattern period according to the PRACH config + LOG_D(MAC,"Build RO list\n"); + build_ro_list(scc, unpaired); + + // Build the list of all the valid/transmitted SSBs according to the config + LOG_D(MAC,"Build SSB list\n"); + build_ssb_list(scc); + + // Map the transmitted SSBs to the ROs and create the association pattern according to the config + LOG_D(MAC,"Map SSB to RO\n"); + map_ssb_to_ro(scc); + LOG_D(MAC,"Map SSB to RO done\n"); +} + +// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x +// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. +// - todo: +// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, int thread_id) { + + uint16_t format, format0, format1, ncs; + int is_nr_prach_slot; + prach_occasion_info_t *prach_occasion_info_p; + + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + RA_config_t *ra = &mac->ra; + + //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; + fapi_nr_ul_config_prach_pdu *prach_config_pdu; + fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + fapi_nr_prach_config_t *prach_config = &cfg->prach_config; + nr_scheduled_response_t scheduled_response; + + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + + ra->RA_offset = 2; // to compensate the rx frame offset at the gNB + ra->generate_nr_prach = 0; // Reset flag for PRACH generation + + if (is_nr_UL_slot(scc, slotP)) { + + // WIP Need to get the proper selected ssb_idx + // Initial beam selection functionality is not available yet + uint8_t selected_gnb_ssb_idx = mac->mib_ssb; + + // Get any valid PRACH occasion in the current slot for the selected SSB index + is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx, + (int)frameP, + (int)slotP, + &prach_occasion_info_p); + + if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) { + AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); + + ra->generate_nr_prach = 1; + + format = prach_occasion_info_p->format; + format0 = format & 0xff; // single PRACH format + format1 = (format >> 8) & 0xff; // dual PRACH format + + ul_config->sfn = frameP; + ul_config->slot = slotP; + + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; + prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; + memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); + ul_config->number_pdus += 1; + LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus); + + ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + + prach_config_pdu->phys_cell_id = *scc->physCellId; + prach_config_pdu->num_prach_ocas = 1; + prach_config_pdu->prach_slot = prach_occasion_info_p->slot; + prach_config_pdu->prach_start_symbol = prach_occasion_info_p->start_symbol; + prach_config_pdu->num_ra = prach_occasion_info_p->fdm; + + prach_config_pdu->num_cs = ncs; + prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].prach_root_sequence_index; + prach_config_pdu->restricted_set = prach_config->restricted_set_config; + prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; + + LOG_D(MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); + + // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) + for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ronb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) { + if (prach_occasion_info_p->mapped_ssb_idx[prach_config_pdu->ssb_nb_in_ro] == selected_gnb_ssb_idx) + break; + } + AssertFatal(prach_config_pdu->ssb_nb_in_ronb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); + + if (format1 != 0xff) { + switch(format0) { // dual PRACH format + case 0xa1: + prach_config_pdu->prach_format = 11; + break; + case 0xa2: + prach_config_pdu->prach_format = 12; + break; + case 0xa3: + prach_config_pdu->prach_format = 13; + break; + default: + AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } else { + switch(format0) { // single PRACH format + case 0: + prach_config_pdu->prach_format = 0; + break; + case 1: + prach_config_pdu->prach_format = 1; + break; + case 2: + prach_config_pdu->prach_format = 2; + break; + case 3: + prach_config_pdu->prach_format = 3; + break; + case 0xa1: + prach_config_pdu->prach_format = 4; + break; + case 0xa2: + prach_config_pdu->prach_format = 5; + break; + case 0xa3: + prach_config_pdu->prach_format = 6; + break; + case 0xb1: + prach_config_pdu->prach_format = 7; + break; + case 0xb4: + prach_config_pdu->prach_format = 8; + break; + case 0xc0: + prach_config_pdu->prach_format = 9; + break; + case 0xc2: + prach_config_pdu->prach_format = 10; + break; + default: + AssertFatal(1 == 0, "Invalid PRACH format"); + } + } // if format1 + } // is_nr_prach_slot + + fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id); + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + mac->if_module->scheduled_response(&scheduled_response); + } // if is_nr_UL_slot +} + +uint8_t +nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) { + uint8_t total_rlc_pdu_header_len = 0; + int16_t buflen_remain = 0; + uint8_t lcid = 0; + uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + uint16_t payload_offset = 0, num_sdus = 0; + uint8_t ulsch_sdus[MAX_ULSCH_PAYLOAD_BYTES]; + uint16_t sdu_length_total = 0; + //unsigned short post_padding = 0; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + + rlc_buffer_occupancy_t lcid_buffer_occupancy_old = + 0, lcid_buffer_occupancy_new = 0; + LOG_D(MAC, + "[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n", + module_idP, frameP, subframe, buflen); + AssertFatal(CC_id == 0, + "Transmission on secondary CCs is not supported yet\n"); + + // Check for DCCH first + // TO DO: Multiplex in the order defined by the logical channel prioritization + for (lcid = UL_SCH_LCID_SRB1; + lcid < NR_MAX_NUM_LCID; lcid++) { + + lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind(module_idP, mac->crnti, eNB_index, frameP, subframe, ENB_FLAG_NO, lcid); + lcid_buffer_occupancy_new = lcid_buffer_occupancy_old; + + if(lcid_buffer_occupancy_new){ + + buflen_remain = + buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + LOG_D(MAC, + "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to " + "send (Transport Block size %d SDU Length Total %d , mac header len %d, buflen_remain %d )\n", //BSR byte before Tx=%d + module_idP, frameP, lcid, lcid_buffer_occupancy_new, + buflen, sdu_length_total, + total_rlc_pdu_header_len, buflen_remain); // ,nr_ue_mac_inst->scheduling_info.BSR_bytes[nr_ue_mac_inst->scheduling_info.LCGID[lcid]] + + while(buflen_remain > 0 && lcid_buffer_occupancy_new){ + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + mac->crnti, + eNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + lcid, + buflen_remain, + (char *)&ulsch_sdus[sdu_length_total],0, + 0); + + AssertFatal(buflen_remain >= sdu_lengths[num_sdus], + "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n", + lcid, sdu_lengths[num_sdus], buflen_remain); + + if (sdu_lengths[num_sdus]) { + sdu_length_total += sdu_lengths[num_sdus]; + sdu_lcids[num_sdus] = lcid; + + total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last; + + //Update number of SDU + num_sdus++; + } + + /* Get updated BO after multiplexing this PDU */ + lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP, + mac->crnti, + eNB_index, + frameP, + subframe, + ENB_FLAG_NO, + lcid); + buflen_remain = + buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + } + } + +} + + // Generate ULSCH PDU + if (num_sdus>0) { + payload_offset = nr_generate_ulsch_pdu(ulsch_sdus, + ulsch_buffer, // mac header + num_sdus, // num sdus + sdu_lengths, // sdu length + sdu_lcids, // sdu lcid + 0, // power_headroom + mac->crnti, // crnti + 0, // truncated_bsr + 0, // short_bsr + 0, // long_bsr + 0, // post_padding + buflen); // TBS in bytes + } + else + return 0; + + // Padding: fill remainder of ULSCH with 0 + if (buflen - payload_offset > 0){ + for (int j = payload_offset; j < buflen; j++) + ulsch_buffer[j] = 0; + } + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing UL MAC payload UE side, payload_offset: %d \n", payload_offset); + for (int i = 0; i < buflen ; i++) { + //harq_process_ul_ue->a[i] = (unsigned char) rand(); + //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + printf("%02x ",(unsigned char)ulsch_buffer[i]); + } + printf("\n"); +#endif + + return 1; +} diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c deleted file mode 100644 index 06db41df9c..0000000000 --- a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c +++ /dev/null @@ -1,350 +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 rar_tools_nrUE.c - * \brief RA tools for NR UE - * \author Guido Casati - * \date 2019 - * \version 1.0 - * @ingroup _mac - - */ - -/* Sim */ -#include "SIMULATION/TOOLS/sim.h" - -/* Utils */ -#include "common/utils/LOG/log.h" -#include "OCG.h" -#include "OCG_extern.h" -#include "UTIL/OPT/opt.h" - -/* Common */ -#include "common/ran_context.h" - -/* MAC */ -#include "NR_MAC_UE/mac.h" -#include "NR_MAC_UE/mac_proto.h" -#include "NR_MAC_COMMON/nr_mac_extern.h" -#include - -// #define DEBUG_RAR -// #define DEBUG_MSG3 - -// table 7.2-1 TS 38.321 -uint16_t table_7_2_1[16] = { - 5, // row index 0 - 10, // row index 1 - 20, // row index 2 - 30, // row index 3 - 40, // row index 4 - 60, // row index 5 - 80, // row index 6 - 120, // row index 7 - 160, // row index 8 - 240, // row index 9 - 320, // row index 10 - 480, // row index 11 - 960, // row index 12 - 1920, // row index 13 -}; - -void nr_config_Msg3_pdu(NR_UE_MAC_INST_t *mac, - int Msg3_f_alloc, - uint8_t Msg3_t_alloc, - uint8_t mcs, - uint8_t freq_hopping){ - - int f_alloc, mask, StartSymbolIndex, NrOfSymbols; - uint8_t nb_dmrs_re_per_rb; - uint16_t number_dmrs_symbols = 0; - int N_PRB_oh; - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; - nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pusch_config_pdu; - NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[0]; - NR_BWP_UplinkDedicated_t *ibwp = mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - NR_PUSCH_Config_t *pusch_Config = ibwp->pusch_Config->choice.setup; - int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[Msg3_t_alloc]->startSymbolAndLength; - - #ifdef DEBUG_MSG3 - printf("[DEBUG_MSG3] Configuring 1 Msg3 PDU of %d UL pdus \n", ul_config->number_pdus); - #endif - - // Num PRB Overhead from PUSCH-ServingCellConfig - if (mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead == NULL) - N_PRB_oh = 0; - else - N_PRB_oh = *mac->scg->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->xOverhead; - - // active BWP start - int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); - int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); - - // initial BWP start - int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275); - int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275); - - // BWP start selection according to 8.3 of TS 38.213 - pusch_config_pdu->bwp_size = ibwp_size; - if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) - pusch_config_pdu->bwp_start = abwp_start; - else - pusch_config_pdu->bwp_start = ibwp_start; - - //// Resource assignment from RAR - // Frequency domain allocation according to 8.3 of TS 38.213 - if (ibwp_size < 180) - mask = (1 << ((int) ceil(log2((ibwp_size*(ibwp_size+1))>>1)))) - 1; - else - mask = (1 << (28 - (int)(ceil(log2((ibwp_size*(ibwp_size+1))>>1))))) - 1; - f_alloc = Msg3_f_alloc & mask; - nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu, NULL, ibwp_size, 0, f_alloc); - - // virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211) - pusch_config_pdu->rb_start += ibwp_start - abwp_start; - - // Time domain allocation - SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); - pusch_config_pdu->ul_dmrs_symb_pos = 1<start_symbol_index = StartSymbolIndex; - pusch_config_pdu->nr_of_symbols = NrOfSymbols; - - #ifdef DEBUG_MSG3 - printf("[DEBUG_MSG3] Freq assignment (RB start %d size %d) BWP (start %d, size %d), Time assignment (sliv_S %d sliv_L %d) \n", - pusch_config_pdu->rb_start, - pusch_config_pdu->rb_size, - pusch_config_pdu->bwp_start, - pusch_config_pdu->bwp_size, - StartSymbolIndex, - NrOfSymbols); - #endif - - // MCS - pusch_config_pdu->mcs_index = mcs; - // Frequency hopping - pusch_config_pdu->frequency_hopping = freq_hopping; - // TC-RNTI - pusch_config_pdu->rnti = mac->t_crnti; - - // DM-RS configuration according to 6.2.2 UE DM-RS transmission procedure in 38.214 - pusch_config_pdu->dmrs_config_type = pusch_dmrs_type1; - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; - pusch_config_pdu->dmrs_ports = 1; - get_num_re_dmrs(pusch_config_pdu, - &nb_dmrs_re_per_rb, - &number_dmrs_symbols); - - // DMRS sequence initialization [TS 38.211, sec 6.4.1.1.1]. - // Should match what is sent in DCI 0_1, otherwise set to 0. - pusch_config_pdu->scid = 0; - - // Transform precoding according to 6.1.3 UE procedure for applying transform precoding on PUSCH in 38.214 - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - pusch_config_pdu->transform_precoding = 1; - else - pusch_config_pdu->transform_precoding = 0; - - // Resource allocation in frequency domain according to 6.1.2.2 in TS 38.214 - pusch_config_pdu->resource_alloc = pusch_Config->resourceAllocation; - - //// Completing PUSCH PDU - pusch_config_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - pusch_config_pdu->mcs_table = 0; - pusch_config_pdu->nrOfLayers = 1; - pusch_config_pdu->cyclic_prefix = 0; - pusch_config_pdu->target_code_rate = nr_get_code_rate_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); - pusch_config_pdu->qam_mod_order = nr_get_Qm_ul(pusch_config_pdu->mcs_index, pusch_config_pdu->mcs_table); - pusch_config_pdu->data_scrambling_id = *scc->physCellId; - pusch_config_pdu->ul_dmrs_scrambling_id = *scc->physCellId; - pusch_config_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - pusch_config_pdu->vrb_to_prb_mapping = 0; - pusch_config_pdu->uplink_frequency_shift_7p5khz = 0; - //Optional Data only included if indicated in pduBitmap - pusch_config_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213 - pusch_config_pdu->pusch_data.harq_process_id = 0; - pusch_config_pdu->pusch_data.new_data_indicator = 1; // new data - pusch_config_pdu->pusch_data.num_cb = 0; - - // Compute TBS - pusch_config_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_config_pdu->qam_mod_order, - pusch_config_pdu->target_code_rate, - pusch_config_pdu->rb_size, - pusch_config_pdu->nr_of_symbols, - nb_dmrs_re_per_rb*number_dmrs_symbols, - N_PRB_oh, - 0, // TBR to verify tb scaling - pusch_config_pdu->nrOfLayers)/8; - -} - -///////////////////////////////////// -// Random Access Response PDU // -// TS 38.213 ch 8.2 // -// TS 38.321 ch 6.2.3 // -///////////////////////////////////// -//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise -//| E | T | R A P I D |// -//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// -//| R | T A |// -//| T A | UL grant |// -//| UL grant |// -//| UL grant |// -//| UL grant |// -//| T C - R N T I |// -//| T C - R N T I |// -///////////////////////////////////// -// UL grant (27 bits) // -///////////////////////////////////// -//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise -//|-------------------|FHF|F_alloc|// -//| Freq allocation |// -//| F_alloc |Time allocation|// -//| MCS | TPC |CSI|// -///////////////////////////////////// -// TbD WIP Msg3 development ongoing -// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213 -// - apply tpc command -uint16_t nr_ue_process_rar(module_id_t mod_id, - int CC_id, - frame_t frame, - sub_frame_t slot, - uint8_t * dlsch_buffer, - rnti_t * t_crnti, - uint8_t preamble_index, - uint8_t * selected_rar_buffer){ - - NR_UE_MAC_INST_t *ue_mac = get_mac_inst(mod_id); - NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer - NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer - uint8_t n_subPDUs = 0; // number of RAR payloads - uint8_t n_subheaders = 0; // number of MAC RAR subheaders - uint16_t ta_command = 0; - - AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n"); - - while (1) { - n_subheaders++; - if (rarh->T == 1) { - n_subPDUs++; - LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id); - } else { - n_subPDUs++; - ue_mac->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; - ue_mac->RA_BI_found = 1; - LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ue_mac->RA_backoff_indicator); - } - if (rarh->RAPID == preamble_index) { - LOG_I(PHY, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); - rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); - ue_mac->RA_RAPID_found = 1; - break; - } - if (rarh->E == 0) { - LOG_I(PHY, "No RAR found with the intended RAPID. \n"); - break; - } else { - rarh += sizeof(NR_MAC_RAR) + 1; - } - }; - - #ifdef DEBUG_RAR - LOG_D(MAC, "[DEBUG_RAR] (%d,%d) number of RAR subheader %d; number of RAR pyloads %d\n", frame, slot, n_subheaders, n_subPDUs); - LOG_D(MAC, "[DEBUG_RAR] Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); - #endif - - if (ue_mac->RA_RAPID_found) { - - uint8_t freq_hopping, mcs, Msg3_t_alloc, Msg3_f_alloc; - unsigned char tpc_command, csi_req; - - // TC-RNTI - *t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); - ue_mac->t_crnti = *t_crnti; - // TA command - ta_command = rar->TA2 + (rar->TA1 << 5); - // CSI - csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01); - // TPC - tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07); - switch (tpc_command){ - case 0: - ue_mac->Msg3_TPC = -6; - break; - case 1: - ue_mac->Msg3_TPC = -4; - break; - case 2: - ue_mac->Msg3_TPC = -2; - break; - case 3: - ue_mac->Msg3_TPC = 0; - break; - case 4: - ue_mac->Msg3_TPC = 2; - break; - case 5: - ue_mac->Msg3_TPC = 4; - break; - case 6: - ue_mac->Msg3_TPC = 6; - break; - case 7: - ue_mac->Msg3_TPC = 8; - break; - } - // MCS - mcs = (unsigned char) (rar->UL_GRANT_4 >> 4); - // time alloc - Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07); - // frequency alloc - Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); - // frequency hopping - freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); - - #ifdef DEBUG_RAR - LOG_D(MAC, "[DEBUG_RAR] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n", - Msg3_t_alloc, - Msg3_f_alloc, - ta_command, - mcs, - freq_hopping, - tpc_command, - csi_req, - ue_mac->t_crnti); - #endif - - // Config Msg3 PDU - nr_config_Msg3_pdu(ue_mac, Msg3_f_alloc, Msg3_t_alloc, mcs, freq_hopping); - // Schedule Msg3 - nr_ue_msg3_scheduler(ue_mac, frame, slot, Msg3_t_alloc); - - } else { - ue_mac->t_crnti = 0; - ta_command = (0xffff); - } - - // move the selected RAR to the front of the RA_PDSCH buffer - memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1); - memcpy((void *) (selected_rar_buffer + 1), (void *) rar, sizeof(NR_MAC_RAR)); - - return ta_command; -} diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 3a860b80a3..6aa906b82b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -124,15 +124,11 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm } } + uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + frequency_range_t frequency_range = band<100?FR1:FR2; + lte_frame_type_t frame_type; - uint16_t band; - int32_t offset; - - get_band((cfg->carrier_config.dl_frequency.value)*1000, - &band, - &offset, - &frame_type); - + get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type); RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type; // Cell configuration @@ -150,6 +146,10 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm cfg->ssb_config.ss_pbch_power.tl.tag = NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG; cfg->num_tlv++; + cfg->ssb_config.bch_payload.value = 1; + cfg->ssb_config.bch_payload.tl.tag = NFAPI_NR_CONFIG_BCH_PAYLOAD_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++; @@ -173,6 +173,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm 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->prach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + cfg->prach_config.prach_ConfigurationIndex.tl.tag = NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG; + cfg->num_tlv++; switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) { case 0 : @@ -193,26 +196,30 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm cfg->prach_config.num_prach_fd_occasions.tl.tag = NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG; cfg->num_tlv++; + cfg->prach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + cfg->prach_config.prach_ConfigurationIndex.tl.tag = NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_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; +// 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.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i); +//k1= msg1_FrequencyStart + 12 (no. of FDM)(RB for PRACH occasion); 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_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, - nb_preambles, frame_type); + cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,nb_preambles, frame_type, frequency_range); cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG; cfg->num_tlv++; - //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = ??? + cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = 1; } cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1; @@ -248,8 +255,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm 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+4]<ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<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){ + LOG_I(MAC,"Setting TDD configuration period to %d\n",cfg->tdd_table.tdd_period.value); int return_tdd = set_tdd_config_nr(cfg, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing, scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots, @@ -295,16 +302,17 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm 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"); + if (return_tdd != 0) + LOG_E(MAC,"TDD configuration can not be done\n"); + else + LOG_I(MAC,"TDD has been properly configurated\n"); } } +extern uint16_t sl_ahead; int rrc_mac_config_req_gNB(module_id_t Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, @@ -318,6 +326,38 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, if (scc != NULL ) { AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present); + /* dimension UL_tti_req_ahead for number of slots in frame */ + const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; + const int n = slots_per_frame[*scc->ssbSubcarrierSpacing]; + RC.nrmac[Mod_idP]->UL_tti_req_ahead[0] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t)); + AssertFatal(RC.nrmac[Mod_idP]->UL_tti_req_ahead[0], + "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n"); + /* fill in slot/frame numbers: slot is fixed, frame will be updated by + * scheduler */ + for (int i = 0; i < n; ++i) { + nfapi_nr_ul_tti_request_t *req = &RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][i]; + /* consider that scheduler runs sl_ahead: the first sl_ahead slots are + * already "in the past" and thus we put frame 1 instead of 0! Note that + * variable sl_ahead seems to not be correctly initialized, but I leave + * it for information purposes here (the fix would always put 0, what + * happens now, too) */ + req->SFN = i < sl_ahead; + req->Slot = i; + } + + RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL = + calloc(n * MAX_BWP_SIZE, sizeof(uint16_t)); + AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL, + "could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n"); + + for (int i = 0; i < MAX_NUM_BWP; ++i) { + RC.nrmac[Mod_idP]->pucch_index_used[i] = + calloc(n, sizeof(*RC.nrmac[Mod_idP]->pucch_index_used)); + AssertFatal(RC.nrmac[Mod_idP]->pucch_index_used[i], + "could not allocate memory for RC.nrmac[]->pucch_index_used[%d]\n", + i); + } + LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n"); config_common(Mod_idP, @@ -345,23 +385,19 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, 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); + if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg); + + find_SSB_and_RO_available(Mod_idP); + } if (secondaryCellGroup) { + RC.nrmac[Mod_idP]->secondaryCellGroupCommon = secondaryCellGroup; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; if (add_ue == 1 && get_softmodem_params()->phy_test) { - const int UE_id = add_new_nr_ue(Mod_idP,rnti); - UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup; - compute_csi_bitlen (secondaryCellGroup, UE_info, UE_id); - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; - AssertFatal(bwpList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - bwpList->list.count); - const int bwp_id = 1; - UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1]; + const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup); LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti); } else if (add_ue == 1 && !get_softmodem_params()->phy_test) { /* TODO: should check for free RA process */ @@ -369,12 +405,18 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0]; ra->state = RA_IDLE; ra->secondaryCellGroup = secondaryCellGroup; - ra->crnti = rnti; - uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count; - ra->preambles.num_preambles = num_preamble; - ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); - for (int i = 0; i < num_preamble; i++) - ra->preambles.preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) { + if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) { + ra->cfra = true; + ra->rnti = rnti; + struct NR_CFRA cfra = *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra; + uint8_t num_preamble = cfra.resources.choice.ssb->ssb_ResourceList.list.count; + ra->preambles.num_preambles = num_preamble; + ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); + for (int i = 0; i < num_preamble; i++) + ra->preambles.preamble_list[i] = cfra.resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + } + } LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti); } else { // secondaryCellGroup has been updated const int UE_id = find_nr_UE_id(Mod_idP,rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 74fa7a2074..1c1ac64672 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -32,9 +32,7 @@ #include "assertions.h" -#include "LAYER2/MAC/mac.h" #include "NR_MAC_COMMON/nr_mac_extern.h" -#include "LAYER2/MAC/mac_proto.h" #include "NR_MAC_gNB/mac_proto.h" #include "common/utils/LOG/log.h" @@ -51,39 +49,41 @@ #include "openair1/PHY/defs_gNB.h" #include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h" -//Agent-related headers -#include "flexran_agent_extern.h" -#include "flexran_agent_mac.h" - #include "intertask_interface.h" #include "executables/softmodem-common.h" -const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; void clear_mac_stats(gNB_MAC_INST *gNB) { memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); } -void dump_mac_stats(gNB_MAC_INST *gNB) { - +void dump_mac_stats(gNB_MAC_INST *gNB) +{ NR_UE_info_t *UE_info = &gNB->UE_info; - NR_mac_stats_t *stats; - int lc_id; - - for (int UE_id=0;UE_idactive[UE_id]) { - LOG_I(MAC, "UE %x\n", UE_info->rnti[UE_id]); - stats = &UE_info->mac_stats[UE_id]; - LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors); - LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes); - LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors); - LOG_I(MAC,"ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",stats->ulsch_total_bytes_scheduled,stats->ulsch_total_bytes_rx); - for (lc_id=0;lc_id<63;lc_id++) { - if (stats->lc_bytes_tx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes TX\n",lc_id,stats->lc_bytes_tx[lc_id]); - if (stats->lc_bytes_rx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes RX\n",lc_id,stats->lc_bytes_rx[lc_id]); - } + int num = 1; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs); + const NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; + LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n", + UE_id, + stats->dlsch_rounds[0], stats->dlsch_rounds[1], + stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors); + LOG_I(MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); + LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n", + UE_id, + stats->ulsch_rounds[0], stats->ulsch_rounds[1], + stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_errors); + LOG_I(MAC, + "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", + UE_id, + stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); + for (int lc_id = 0; lc_id < 63; lc_id++) { + if (stats->lc_bytes_tx[lc_id] > 0) + LOG_I(MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); + if (stats->lc_bytes_rx[lc_id] > 0) + LOG_I(MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); } } } @@ -92,9 +92,13 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, sub_frame_t slotP){ + NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; + const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; 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_dl_tti_pdcch_pdu_rel15_t ***pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***)gNB->pdcch_pdu_idx[CC_idP]; + nfapi_nr_ul_tti_request_t *future_ul_tti_req = + &gNB->UL_tti_req_ahead[CC_idP][(slotP + num_slots - 1) % num_slots]; 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]; @@ -107,17 +111,23 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, 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; + memset(pdcch, 0, sizeof(**pdcch) * MAX_NUM_BWP * MAX_NUM_CORESET); 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; + /* advance last round's future UL_tti_req to be ahead of current frame/slot */ + future_ul_tti_req->SFN = (slotP == 0 ? frameP : frameP + 1) % 1024; + /* future_ul_tti_req->Slot is fixed! */ + future_ul_tti_req->n_pdus = 0; + future_ul_tti_req->n_ulsch = 0; + future_ul_tti_req->n_ulcch = 0; + future_ul_tti_req->n_group = 0; + + /* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e., + * it walks over UL_tti_req_ahead in a circular fashion */ + gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][slotP]; TX_req[CC_idP].Number_of_PDUs = 0; @@ -285,58 +295,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram */ -/* -void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) -{ - int CC_id; - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - nfapi_ul_config_request_t *ul_req = &mac->UL_tti_req[CC_id]; - - *ul_req = *ul_req_tmp; - - // Restore the pointer - ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu; - ul_req->sfn_sf = (frameP<<7) + slotP; - ul_req_tmp->ul_config_request_body.number_of_pdus = 0; - - if (ul_req->ul_config_request_body.number_of_pdus>0) - { - LOG_D(PHY, "%s() active NOW (frameP:%d slotP:%d) pdus:%d\n", __FUNCTION__, frameP, slotP, ul_req->ul_config_request_body.number_of_pdus); - } - - memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list, - (void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list, - ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t)); - } -} -*/ - -void nr_schedule_pusch(int Mod_idP, - int UE_id, - int num_slots_per_tdd, - int ul_slots, - frame_t frameP, - sub_frame_t slotP) { - - nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - int k = slotP + ul_slots - num_slots_per_tdd; - NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k]; - if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) { - UL_tti_req->SFN = pusch->frame; - UL_tti_req->Slot = pusch->slot; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu; - UL_tti_req->n_pdus+=1; - memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], - 0, sizeof(NR_sched_pusch)); - } -} - bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { return (bitmap >> slot) & 0x01; } @@ -348,17 +306,54 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); - const int UE_id = 0; + int nb_periods_per_frame; + const int bwp_id = 1; gNB_MAC_INST *gNB = RC.nrmac[module_idP]; - NR_UE_info_t *UE_info = &gNB->UE_info; - NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; - const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); + + switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) { + case 0: + nb_periods_per_frame = 20; // 10ms/0p5ms + break; + + 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 %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); + } + + int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame; + const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); start_meas(&RC.nrmac[module_idP]->eNB_scheduler); @@ -372,83 +367,84 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); } - const uint64_t dlsch_in_slot_bitmap = (1 << 1); - const uint64_t ulsch_in_slot_bitmap = (1 << 8); +#define BIT(x) (1 << (x)) + const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6) + | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16); + const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18); memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0 memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1 + NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) + for (int i=0; inum_pdcch_cand[UE_id][i] = 0; for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { //mbsfn_status[CC_id] = 0; // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 275); - memset(cc[CC_id].vrb_map_UL, 0, 275); + memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * MAX_BWP_SIZE); + // clear last scheduled slot's content (only)! + const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int last_slot = (slot + num_slots - 1) % num_slots; + uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL; + memset(&vrb_map_UL[last_slot * MAX_BWP_SIZE], 0, sizeof(uint16_t) * MAX_BWP_SIZE); clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot); } + if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]); + // This schedules MIB - if((slot == 0) && (frame & 7) == 0){ - schedule_nr_mib(module_idP, frame, slot); - } + schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]); + + // This schedules SIB1 + if ( get_softmodem_params()->sa == 1 ) + schedule_nr_sib1(module_idP, frame, slot); + // This schedule PRACH if we are not in phy_test mode - if (get_softmodem_params()->phy_test == 0) - schedule_nr_prach(module_idP, frame, slot); + if (get_softmodem_params()->phy_test == 0) { + /* we need to make sure that resources for PRACH are free. To avoid that + e.g. PUSCH has already been scheduled, make sure we schedule before + anything else: below, we simply assume an advance one frame (minus one + slot, because otherwise we would allocate the current slot in + UL_tti_req_ahead), but be aware that, e.g., K2 is allowed to be larger + (schedule_nr_prach will assert if resources are not free). */ + const sub_frame_t n_slots_ahead = nr_slots_per_frame[*scc->ssbSubcarrierSpacing] - 1; + const frame_t f = (frame + (slot + n_slots_ahead) / nr_slots_per_frame[*scc->ssbSubcarrierSpacing]) % 1024; + const sub_frame_t s = (slot + n_slots_ahead) % nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + schedule_nr_prach(module_idP, f, s); + } // This schedule SR // TODO - // This schedule CSI-RS transmission and measurement reporting - if (UE_info->active[UE_id]){ - nr_csirs_scheduling(module_idP, UE_id, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]); - nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, slots_per_frame[*scc->ssbSubcarrierSpacing]); - } + // Schedule CSI-RS transmission + //nr_csirs_scheduling(module_idP, UE_id, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]); + + // Schedule CSI measurement reporting: check in slot 0 for the whole frame + if (slot == 0) + nr_csi_meas_reporting(module_idP, frame, slot); // This schedule RA procedure if not in phy_test mode // Otherwise already consider 5G already connected if (get_softmodem_params()->phy_test == 0) { nr_schedule_RA(module_idP, frame, slot); - nr_schedule_reception_msg3(module_idP, 0, frame, slot); - } - - if (UE_info->active[UE_id]) { - // TbD once RACH is available, start ta_timer when UE is connected - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; - if (ue_sched_ctl->ta_timer == 0) { - ue_sched_ctl->ta_apply = true; - /* if time is up, then set the timer to not send it for 5 frames - // regardless of the TA value */ - ue_sched_ctl->ta_timer = 100; - } } // This schedules the DCI for Uplink and subsequently PUSCH - // The decision about whether to schedule is done for each UE independently - // inside - if (UE_info->active[UE_id] && slot < 10) { - int tda = 1; // time domain assignment hardcoded for now - schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap); - nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot); + { + nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap); } - if (UE_info->active[UE_id] - && (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd)) - && (!get_softmodem_params()->phy_test || slot == 1) - && slot < 10) { - ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd; - //int pucch_sched; - //nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched); - //nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_info->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL); - nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd); - ue_sched_ctl->ta_apply = false; - } + // This schedules the DCI for Downlink and PDSCH + if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot)) + nr_schedule_ue_spec(module_idP, frame, slot); - if (UE_info->active[UE_id]) - nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot); + + nr_schedule_pucch(module_idP, frame, slot); stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 413727b9cb..b914e80d23 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -43,27 +43,188 @@ extern RAN_CONTEXT_t RC; extern const uint8_t nr_slots_per_frame[5]; +extern uint16_t sl_ahead; uint8_t DELTA[4]= {2,3,4,6}; -void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { +#define MAX_NUMBER_OF_SSB 64 +float ssb_per_rach_occasion[8] = {0.125,0.25,0.5,1,2,4,8}; +int16_t ssb_index_from_prach(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + uint16_t preamble_index, + uint8_t freq_index, + uint8_t symbol) { + + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &gNB->common_channels[0]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; + + uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; + + uint8_t total_RApreambles = 64; + if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) + total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + + float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; + uint16_t start_symbol_index = 0; + uint8_t mu,N_dur=0,N_t_slot=0,start_symbol = 0, temp_start_symbol = 0, N_RA_slot=0; + uint16_t format,RA_sfn_index = -1; + uint8_t config_period = 1; + uint16_t prach_occasion_id = -1; + uint8_t num_active_ssb = cc->num_active_ssb; + + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) + mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + else + mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + get_nr_prach_info_from_index(config_index, + (int)frameP, + (int)slotP, + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, + mu, + cc->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur, + &RA_sfn_index, + &N_RA_slot, + &config_period); + uint8_t index = 0,slot_index = 0; + for (slot_index = 0;slot_index < N_RA_slot; slot_index++) { + if (N_RA_slot <= 1) { //1 PRACH slot in a subframe + if((mu == 1) || (mu == 3)) + slot_index = 1; //For scs = 30khz and 120khz + } + for (int i=0; i< N_t_slot; i++) { + temp_start_symbol = (start_symbol + i * N_dur + 14 * slot_index) % 14; + if(symbol == temp_start_symbol) { + start_symbol_index = i; + break; + } + } + } + if (N_RA_slot <= 1) { //1 PRACH slot in a subframe + if((mu == 1) || (mu == 3)) + slot_index = 0; //For scs = 30khz and 120khz + } + + // prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index; + prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period)*cc->total_prach_occasions_per_config_period) + + (RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index; + + //one RO is shared by one or more SSB + if(num_ssb_per_RO <= 1 ) + index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb; + //one SSB have more than one continuous RO + else if ( num_ssb_per_RO > 1) { + index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ; + for(int j = 0;j < num_ssb_per_RO;j++) { + if(preamble_index < (((j+1) * total_RApreambles) / num_ssb_per_RO)) + index = index + j; + } + } + + LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", + frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles); + + return index; +} + + +//Compute Total active SSBs and RO available +void find_SSB_and_RO_available(module_id_t module_idP) { + + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &gNB->common_channels[0]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; + + uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint8_t mu,N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0; + uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0; + uint8_t num_active_ssb = 0; + uint8_t max_association_period = 1; + + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) + mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + else + mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4 + get_nr_prach_occasion_info_from_index(config_index, + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, + mu, + cc->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur, + &N_RA_slot, + &N_RA_sfn, + &max_association_period); + + float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value]; + uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; + uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ; + uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm; + + for(int i = 0;i < 64;i++) { + if ((L_ssb >> (63-i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1 + cc->ssb_index[num_active_ssb] = i; + num_active_ssb++; + } + } + + for(int i = 1; (1 << (i-1)) <= max_association_period;i++) { + if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) { + repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb); + break; + } + else { + total_RA_occasions = total_RA_occasions * i; + cc->max_association_period = i; + } + } + if(cc->max_association_period == 0) + cc->max_association_period = 1; + + unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO); + cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion; + cc->num_active_ssb = num_active_ssb; + + LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n", + cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn); +} + +void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) +{ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0]; + nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP]; + nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; if (is_nr_UL_slot(scc,slotP)) { - uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; - uint8_t mu,N_dur,N_t_slot,start_symbol; + uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot; + uint16_t RA_sfn_index = -1; + uint8_t config_period = 1; uint16_t format; + int slot_index = 0; + uint16_t prach_occasion_id = -1; if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; else mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value; // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4 if ( get_nr_prach_info_from_index(config_index, (int)frameP, @@ -74,89 +235,109 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP &format, &start_symbol, &N_t_slot, - &N_dur) ) { + &N_dur, + &RA_sfn_index, + &N_RA_slot, + &config_period) ) { - int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM; uint16_t format0 = format&0xff; // first column of format from table uint16_t format1 = (format>>8)&0xff; // second column of format from table + if (N_RA_slot > 1) { //more than 1 PRACH slot in a subframe + if (slotP%2 == 1) + slot_index = 1; + else + slot_index = 0; + }else if (N_RA_slot <= 1) { //1 PRACH slot in a subframe + slot_index = 0; + } + UL_tti_req->SFN = frameP; UL_tti_req->Slot = slotP; - for (int n=0; n<(1<pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t); - nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu; - memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t)); - UL_tti_req->n_pdus+=1; + for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion + for (int td_index=0; td_indexphys_cell_id = *scc->physCellId; - prach_pdu->num_prach_ocas = N_t_slot; - prach_pdu->prach_start_symbol = start_symbol; - prach_pdu->num_ra = n; - prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig, - format0, - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig); - // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities - // We added 9 = A1/B1 10 = A2/B2 11 A3/B3 - if (format1!=0xff) { - switch(format0) { - case 0xa1: - prach_pdu->prach_format = 9; - break; - case 0xa2: - prach_pdu->prach_format = 10; - break; - case 0xa3: - prach_pdu->prach_format = 11; - break; - default: - AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); - } - } - else{ - switch(format0) { - case 0xa1: - prach_pdu->prach_format = 0; - break; - case 0xa2: - prach_pdu->prach_format = 1; - break; - case 0xa3: - prach_pdu->prach_format = 2; - break; - case 0xb1: - prach_pdu->prach_format = 3; - break; - case 0xb2: - prach_pdu->prach_format = 4; - break; - case 0xb3: - prach_pdu->prach_format = 5; - break; - case 0xb4: - prach_pdu->prach_format = 6; - break; - case 0xc0: - prach_pdu->prach_format = 7; - break; - case 0xc2: - prach_pdu->prach_format = 8; - break; - case 0: - // long formats are handled @ PHY - break; - case 1: - // long formats are handled @ PHY - break; - case 2: - // long formats are handled @ PHY - break; - case 3: - // long formats are handled @ PHY - break; - default: - AssertFatal(1==0,"Invalid PRACH format"); + prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + + (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index; + + if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){ + + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t); + nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu; + memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t)); + UL_tti_req->n_pdus+=1; + + // filling the prach fapi structure + prach_pdu->phys_cell_id = *scc->physCellId; + prach_pdu->num_prach_ocas = N_t_slot; + prach_pdu->prach_start_symbol = start_symbol; + prach_pdu->num_ra = fdm_index; + prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig, + format0, + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig); + + LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n", + frameP, slotP, + prach_occasion_id, prach_pdu->num_ra, + prach_pdu->prach_start_symbol, + slot_index, RA_sfn_index); + // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities + // We added 9 = A1/B1 10 = A2/B2 11 A3/B3 + if (format1!=0xff) { + switch(format0) { + case 0xa1: + prach_pdu->prach_format = 11; + break; + case 0xa2: + prach_pdu->prach_format = 12; + break; + case 0xa3: + prach_pdu->prach_format = 13; + break; + default: + AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } + else{ + switch(format0) { + case 0: + prach_pdu->prach_format = 0; + break; + case 1: + prach_pdu->prach_format = 1; + break; + case 2: + prach_pdu->prach_format = 2; + break; + case 3: + prach_pdu->prach_format = 3; + break; + case 0xa1: + prach_pdu->prach_format = 4; + break; + case 0xa2: + prach_pdu->prach_format = 5; + break; + case 0xa3: + prach_pdu->prach_format = 6; + break; + case 0xb1: + prach_pdu->prach_format = 7; + break; + case 0xb4: + prach_pdu->prach_format = 8; + break; + case 0xc0: + prach_pdu->prach_format = 9; + break; + case 0xc2: + prach_pdu->prach_format = 10; + break; + default: + AssertFatal(1==0,"Invalid PRACH format"); + } + } } } } @@ -168,7 +349,7 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot, NR_ServingCellConfigCommon_t *scc, uint16_t monitoring_slot_period, - uint16_t monitoring_offset){ + uint16_t monitoring_offset,uint8_t index,uint8_t num_active_ssb){ // preferentially we schedule the msg2 in the mixed slot or in the last dl slot // if they are allowed by search space configuration @@ -190,6 +371,13 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + // we can't schedule msg2 before sl_ahead since prach + int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu]; + if ((eff_slot-rach_slot)<=sl_ahead) { + *msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu]; + *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + } + switch(response_window){ case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: slot_window = 1; @@ -222,12 +410,11 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, // slot and frame limit to transmit msg2 according to response window uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu]; - //uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1); - + uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1); // go to previous slot if the current scheduled slot is beyond the response window // and if the slot is not among the PDCCH monitored ones (38.213 10.1) - while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) { + while (((*msg2_slot>slot_limit)&&(*msg2_frame>frame_limit)) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) { if((*msg2_slot%tdd_period_slot) > 0) (*msg2_slot)--; else @@ -247,8 +434,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL NR_SearchSpace_t *ss; - // ra_rnti from 5.1.3 in 38.321 - uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; @@ -256,6 +441,16 @@ void nr_initiate_ra_proc(module_id_t module_idP, NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_RA_t *ra = &cc->ra[0]; + uint16_t ra_rnti; + + // ra_rnti from 5.1.3 in 38.321 + // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here. + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839) + ra_rnti=1+symbol+(9/*slotP*/*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); + else + ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); + + // if the preamble received correspond to one of the listed // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries int pr_found=0; @@ -265,12 +460,13 @@ void nr_initiate_ra_proc(module_id_t module_idP, break; } } + if (!pr_found) { LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n", module_idP, preamble_index); + return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc } - // This should be handled differently when we use the initialBWP for RA ra->bwp_id=1; NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; @@ -280,6 +476,13 @@ void nr_initiate_ra_proc(module_id_t module_idP, LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index); if (ra->state == RA_IDLE) { + + uint8_t beam_index = ssb_index_from_prach(module_idP, + frameP, + slotP, + preamble_index, + freq_index, + symbol); int loop = 0; LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); ra->state = Msg2; @@ -301,33 +504,35 @@ void nr_initiate_ra_proc(module_id_t module_idP, &monitoring_slot_period, &monitoring_offset); - nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset); + nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb); ra->Msg2_frame = msg2_frame; ra->Msg2_slot = msg2_slot; - LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); - - do { - ra->rnti = (taus() % 65518) + 1; - loop++; + LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + if (!ra->cfra) { + do { + ra->rnti = (taus() % 65518) + 1; + loop++; + } + while (loop != 100 && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519)); + if (loop == 100) { + LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } } - while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 65519)); - if (loop == 100) { - LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); - abort(); - } - ra->RA_rnti = ra_rnti; ra->preamble_index = preamble_index; + ra->beam_id = beam_index; - LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n", + LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n", module_idP, CC_id, frameP, ra->Msg2_frame, ra->Msg2_slot, - ra->RA_rnti); + ra->RA_rnti, + cc->ssb_index[beam_index]); return; } @@ -342,30 +547,37 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ int CC_id = 0; gNB_MAC_INST *mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - NR_RA_t *ra = &cc->ra[0]; start_meas(&mac->schedule_ra); - //for (i = 0; i < NR_NB_RA_PROC_MAX; i++) { +// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { +// for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { + +// NR_RA_t *ra = &cc->ra[i]; + NR_RA_t *ra = &cc->ra[0]; + LOG_D(MAC,"RA[state:%d]\n",ra->state); switch (ra->state){ case Msg2: nr_generate_Msg2(module_idP, CC_id, frameP, slotP); break; case Msg4: - //generate_Msg4(module_idP, CC_id, frameP, slotP, ra); + //generate_Msg4(module_idP, CC_id, frameP, slotP); break; case WAIT_Msg4_ACK: - //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra); + //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP); break; default: break; } - //} +// } +// } stop_meas(&mac->schedule_ra); } -void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc, +void nr_get_Msg3alloc(module_id_t module_id, + int CC_id, + NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *ubwp, sub_frame_t current_slot, frame_t current_frame, @@ -398,27 +610,26 @@ void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc, else ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]); - ra->msg3_nb_rb = 18; - ra->msg3_first_rb = 0; -} - - -void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - NR_RA_t *ra = &cc->ra[0]; - - if (ra->state == WAIT_Msg3) { - if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot) ){ - ul_req->SFN = ra->Msg3_frame; - ul_req->Slot = ra->Msg3_slot; - ul_req->pdus_list[ul_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; - ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); - ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu; - ul_req->n_pdus+=1; - } + LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex); + uint16_t *vrb_map_UL = + &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; + const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + /* search 18 free RBs */ + int rbSize = 0; + int rbStart = 0; + while (rbSize < 18) { + rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ + rbSize = 0; + while (rbStart < bwpSize && vrb_map_UL[rbStart]) + rbStart++; + AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n"); + while (rbStart + rbSize < bwpSize + && !vrb_map_UL[rbStart + rbSize] + && rbSize < 18) + rbSize++; } + ra->msg3_nb_rb = 18; + ra->msg3_first_rb = rbStart; } void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ @@ -433,10 +644,32 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t return; } - LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + uint16_t *vrb_map_UL = + &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; + for (int i = 0; i < ra->msg3_nb_rb; ++i) { + AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb], + "RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n", + i + ra->msg3_first_rb, + ra->Msg3_frame, + ra->Msg3_slot); + vrb_map_UL[i + ra->msg3_first_rb] = 1; + } - nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu; + LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + + nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot]; + AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame + && future_ul_tti_req->Slot == ra->Msg3_slot, + "future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n", + future_ul_tti_req->SFN, + future_ul_tti_req->Slot, + ra->Msg3_frame, + ra->Msg3_slot); + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); + future_ul_tti_req->n_pdus += 1; AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", @@ -461,10 +694,10 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; pusch_pdu->rnti = ra->rnti; pusch_pdu->handle = 0; - int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); - int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); - int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); - int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); + int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) pusch_pdu->bwp_start = abwp_start; else @@ -530,13 +763,14 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t slotP){ + sub_frame_t slotP) +{ - int dci_formats[2], rnti_types[2], mcsIndex; + int mcsIndex; int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; - NR_RA_t *ra = &cc->ra[0]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_RA_t *ra = &cc->ra[CC_id]; NR_SearchSpace_t *ss = ra->ra_ss; uint16_t RA_rnti = ra->RA_rnti; @@ -553,33 +787,61 @@ void nr_generate_Msg2(module_id_t module_idP, } else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth; - dci10_bw = NRRIV2BW(locationAndBandwidth,275); + dci10_bw = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE); } if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; - nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; - memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - // Checking if the DCI allocation is feasible in current subframe - if (dl_req->nPDUs == NFAPI_NR_MAX_DL_TTI_PDUS) { + if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) { LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti); return; } + uint8_t nr_of_candidates, aggregation_level; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); + NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; + NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */); + int CCEIndex = allocate_nr_CCEs(nr_mac, + bwp, + coreset, + aggregation_level, + 0, // Y + 0, // m + nr_of_candidates); + + if (CCEIndex < 0) { + LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); + return; + } + + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + + /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not + * exist, create it. This is especially important if we have multiple RAs, + * and the DLSCH has to reuse them, so we need to mark them */ + const int bwpid = bwp->bwp_Id; + const int coresetid = coreset->controlResourceSetId; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid]; + if (!pdcch_pdu_rel15) { + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset(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_req->nPDUs += 1; + pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp); + nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15; + } + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + 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)); + dl_req->nPDUs+=1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); // This code from this point on will not work on initialBWP or CORESET0 @@ -590,10 +852,9 @@ void nr_generate_Msg2(module_id_t module_idP, ra->crnti); AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; - LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); + LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); // Qm>2 not allowed for RAR if (get_softmodem_params()->do_ra) @@ -603,11 +864,15 @@ void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->pduBitmap = 0; pdsch_pdu_rel15->rnti = RA_rnti; - pdsch_pdu_rel15->pduIndex = 0; + /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control + * message. This is used to associate control information to data and is + * reset every slot. */ + const int pduindex = nr_mac->pdu_index[CC_id]++; + pdsch_pdu_rel15->pduIndex = pduindex; - 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->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; @@ -653,79 +918,75 @@ void nr_generate_Msg2(module_id_t module_idP, pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols); - dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; - dci_pdu_rel15[0].frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + /* Fill PDCCH DL DCI PDU */ + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; + pdcch_pdu_rel15->numDlDci++; + dci_pdu->RNTI = RA_rnti; + /* TODO: remove next line */ + AssertFatal(ss->searchSpaceType->present != NR_SearchSpace__searchSpaceType_PR_ue_Specific, + "shouldn't the RA SS be common?\n"); + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + dci_pdu->AggregationLevel = aggregation_level; + dci_pdu->CceIndex = CCEIndex; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + dci_pdu_rel15_t dci_payload; + dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart,dci10_bw); - dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; - dci_pdu_rel15[0].vrb_to_prb_mapping.val = 0; - dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; - dci_pdu_rel15[0].tb_scaling = 0; + dci_payload.time_domain_assignment.val = time_domain_assignment; + dci_payload.vrb_to_prb_mapping.val = 0; + dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_payload.tb_scaling = 0; - LOG_I(MAC, "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", - dci_pdu_rel15[0].frequency_domain_assignment.val, - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - dci10_bw, - dci_pdu_rel15[0].time_domain_assignment.val, - dci_pdu_rel15[0].vrb_to_prb_mapping.val, - dci_pdu_rel15[0].mcs, - dci_pdu_rel15[0].tb_scaling); - - uint8_t nr_of_candidates, aggregation_level; - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); - NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */); - int CCEIndex = allocate_nr_CCEs( - nr_mac, - bwp, - coreset, - aggregation_level, - 0, /* n_RNTI 0: common search space */ - 0); // m - - if (CCEIndex < 0) { - LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); - return; - } - nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - RA_rnti, - ss, - coreset, - scc, - bwp, - aggregation_level, - CCEIndex); + LOG_I(MAC, + "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", + dci_payload.frequency_domain_assignment.val, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + dci10_bw, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, + dci_payload.tb_scaling); LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti); - dci_formats[0] = NR_DL_DCI_FORMAT_1_0; - rnti_types[0] = NR_RNTI_RA; + const int dci_format = NR_DL_DCI_FORMAT_1_0; + const int rnti_type = NR_RNTI_RA; - LOG_D(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", - pdcch_pdu_rel15->dci_pdu.RNTI[0], - rnti_types[0], - dci_formats[0], - (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, - pdcch_pdu_rel15->StartSymbolIndex, - pdcch_pdu_rel15->DurationSymbols); + LOG_I(MAC, + "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + pdcch_pdu_rel15->dci_pdu[0].RNTI, + rnti_type, + dci_format, + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); - fill_dci_pdu_rel15(scc,ra->secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id); - - dl_req->nPDUs+=2; + fill_dci_pdu_rel15(scc, + ra->secondaryCellGroup, + dci_pdu, + &dci_payload, + dci_format, + rnti_type, + dci10_bw, + ra->bwp_id); // Program UL processing for Msg3 - nr_get_Msg3alloc(scc, ubwp, slotP, frameP, ra); + nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra); LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); nr_add_msg3(module_idP, CC_id, frameP, slotP); ra->state = WAIT_Msg3; - LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); x_Overhead = 0; - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_pdu_rel15[0].tb_scaling); + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling); // DL TX request tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; - tx_req->PDU_index = nr_mac->pdu_index[CC_id]++; + tx_req->PDU_index = pduindex; tx_req->num_TLV = 1; tx_req->TLVs[0].length = 8; nr_mac->TX_req[CC_id].SFN = frameP; @@ -733,14 +994,19 @@ void nr_generate_Msg2(module_id_t module_idP, nr_mac->TX_req[CC_id].Slot = slotP; memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), + T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */, + T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length)); + /* mark the corresponding RBs as used */ - uint8_t *vrb_map = cc[CC_id].vrb_map; + uint16_t *vrb_map = cc[CC_id].vrb_map; for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1; } } void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){ + NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0]; LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); ra->state = IDLE; @@ -786,7 +1052,7 @@ void nr_fill_rar(uint8_t Mod_idP, uint8_t * dlsch_buffer, nfapi_nr_pusch_pdu_t *pusch_pdu){ - LOG_D(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d ", ra->Msg2_frame, ra-> Msg2_slot); + LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset); NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); unsigned char csi_req = 0, tpc_command; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 989d6fb952..1de46aaea4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -30,6 +30,7 @@ */ +#include "GNB_APP/RRC_nr_paramsvalues.h" #include "assertions.h" #include "NR_MAC_gNB/nr_mac_gNB.h" #include "NR_MAC_gNB/mac_proto.h" @@ -38,24 +39,23 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "OCG.h" -#include "OCG_extern.h" - #include "RRC/NR/nr_rrc_extern.h" +#include "common/utils/nr/nr_common.h" -//#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#include "intertask_interface.h" - #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 #include "common/ran_context.h" -extern RAN_CONTEXT_t RC; +#include "executables/softmodem-common.h" -void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ +extern RAN_CONTEXT_t RC; +extern uint8_t SSB_Table[38]; + +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame){ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc; @@ -67,83 +67,454 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ int mib_sdu_length; int CC_id; - 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_tti_request = &gNB->DL_req[CC_id]; - dl_req = &dl_tti_request->dl_tti_request_body; cc = &gNB->common_channels[CC_id]; + const long band = *cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + const 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); + } - 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 + // scheduling MIB every 8 frames, PHY repeats it in between + if((slotP == 0) && (frameP & 7) == 0) { + dl_tti_request = &gNB->DL_req[CC_id]; + dl_req = &dl_tti_request->dl_tti_request_body; - LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length); + mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); - if (mib_sdu_length > 0) { + LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length); - LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length); + if (mib_sdu_length > 0) { + LOG_D(MAC, + "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", + frameP, + slotP, + dl_req->nPDUs, + mib_sdu_length); - if ((frameP & 1023) < 80){ - LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length); + 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); + } + + 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); + + 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"); + + const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0]; + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB + dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB + 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++; } - 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); - - 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); + // Get type0_PDCCH_CSS_config parameters + NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms; + NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib; + uint8_t gNB_xtra_byte = 0; + for (int i = 0; i < 8; i++) { + gNB_xtra_byte |= ((RC.gNB[module_idP]->pbch.pbch_a >> (31 - i)) & 1) << (7 - i); } - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = 0; //kSSB - dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB - 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++; + get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config, mib, gNB_xtra_byte, frame_parms->Lmax, + frame_parms->ssb_index, frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB); - uint8_t *vrb_map = cc[CC_id].vrb_map; - const int rbStart = dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA; - for (int rb = 0; rb < 20; rb++) - vrb_map[rbStart + rb] = 1; + } + + // checking if there is any SSB in slot + const int abs_slot = (slots_per_frame * frameP) + slotP; + const int slot_per_period = (slots_per_frame>>1)<<(*cc->ServingCellConfigCommon->ssb_periodicityServingCell); + int eff_120_slot; + const BIT_STRING_t *shortBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.shortBitmap; + const BIT_STRING_t *mediumBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.mediumBitmap; + const BIT_STRING_t *longBitmap = &cc->ServingCellConfigCommon->ssb_PositionsInBurst->choice.longBitmap; + uint8_t buf = 0; + switch (cc->ServingCellConfigCommon->ssb_PositionsInBurst->present) { + case 1: + // presence of ssbs possible in the first 2 slots of ssb period + if ((abs_slot % slot_per_period) < 2 && + (((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0) + fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id); + break; + case 2: + // presence of ssbs possible in the first 4 slots of ssb period + if ((abs_slot % slot_per_period) < 4 && + (((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0) + fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id); + break; + case 3: + AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing == + NR_SubcarrierSpacing_kHz120, + "240kHZ subcarrier spacing currently not supported for SSBs\n"); + if ((abs_slot % slot_per_period) < 8) { + eff_120_slot = slotP; + buf = longBitmap->buf[0]; + } else if ((abs_slot % slot_per_period) < 17) { + eff_120_slot = slotP - 9; + buf = longBitmap->buf[1]; + } else if ((abs_slot % slot_per_period) < 26) { + eff_120_slot = slotP - 18; + buf = longBitmap->buf[2]; + } else if ((abs_slot % slot_per_period) < 35) { + eff_120_slot = slotP - 27; + buf = longBitmap->buf[3]; + } + if (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0) + fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id); + break; + default: + AssertFatal(0, + "SSB bitmap size value %d undefined (allowed values 1,2,3)\n", + cc->ServingCellConfigCommon->ssb_PositionsInBurst->present); } } } +void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { +//---------------------------------------- +} + +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) { + uint16_t *vrb_map = cc[CC_id].vrb_map; + for (int rb = 0; rb < 20; rb++) + vrb_map[rbStart + rb] = 1; +} + +void schedule_control_sib1(module_id_t module_id, + int CC_id, + int time_domain_allocation, + uint8_t mcsTableIdx, + uint8_t mcs, + int num_total_bytes) { + + gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; + NR_ServingCellConfigCommon_t *servingcellconfigcommon = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + + if (gNB_mac->sched_ctrlCommon == NULL){ + gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon)); + gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space)); + gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp)); + gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset)); + gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp)); + fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space); + fill_default_coresetZero(gNB_mac->sched_ctrlCommon->coreset,servingcellconfigcommon); + fill_default_initialDownlinkBWP(gNB_mac->sched_ctrlCommon->active_bwp,servingcellconfigcommon); + } + gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; + + gNB_mac->sched_ctrlCommon->time_domain_allocation = time_domain_allocation; + gNB_mac->sched_ctrlCommon->mcsTableIdx = mcsTableIdx; + gNB_mac->sched_ctrlCommon->mcs = mcs; + gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes; + + uint8_t nr_of_candidates; + find_aggregation_candidates(&gNB_mac->sched_ctrlCommon->aggregation_level, &nr_of_candidates, gNB_mac->sched_ctrlCommon->search_space); + + gNB_mac->sched_ctrlCommon->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], + gNB_mac->sched_ctrlCommon->active_bwp, + gNB_mac->sched_ctrlCommon->coreset, + gNB_mac->sched_ctrlCommon->aggregation_level, + 0, + 0, + nr_of_candidates); + + if (gNB_mac->sched_ctrlCommon->cce_index < 0) { + LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__); + return; + } + + const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs; + int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb; + + // Calculate number of symbols + struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength; + int startSymbolIndex, nrOfSymbols; + SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + + if (nrOfSymbols == 2) { + gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 1; + } else { + gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 2; + } + + // Calculate number of PRB_DMRS + uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; + uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); + uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); + + int rbSize = 0; + uint32_t TBS = 0; + do { + rbSize++; + TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), + nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), + rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3; + + // FIXME: Something is not working in nr_modulation() for TBS = 84, so we need to skip it + } while ( (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes) || (TBS==84) ); + + gNB_mac->sched_ctrlCommon->rbSize = rbSize; + gNB_mac->sched_ctrlCommon->rbStart = 0; + + LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength); + LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex); + LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols); + LOG_D(MAC,"rbSize = %i\n", gNB_mac->sched_ctrlCommon->rbSize); + LOG_D(MAC,"TBS = %i\n", TBS); + + // Mark the corresponding RBs as used + for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->rbSize; rb++) { + vrb_map[rb + rbStart] = 1; + } +} + +void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, + nfapi_nr_dl_tti_request_body_t *dl_req, + uint32_t TBS, + int StartSymbolIndex, + int NrOfSymbols) { + + gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; + NR_COMMON_channels_t *cc = gNB_mac->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_CellGroupConfig_t *secondaryCellGroup = gNB_mac->secondaryCellGroupCommon; + NR_BWP_Downlink_t *bwp = gNB_mac->sched_ctrlCommon->active_bwp; + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + dl_req->nPDUs += 1; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nr_configure_pdcch(pdcch_pdu_rel15, + gNB_mac->sched_ctrlCommon->search_space, + gNB_mac->sched_ctrlCommon->coreset, + scc, + bwp); + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + 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)); + dl_req->nPDUs += 1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + pdcch_pdu_rel15->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = SI_RNTI; + pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++; + + pdsch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs; + pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb; + + pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; + if (bwp->bwp_Common->genericParameters.cyclicPrefix) { + pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix; + } else { + pdsch_pdu_rel15->CyclicPrefix = 0; + } + + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs,0); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->mcs; + pdsch_pdu_rel15->mcsTable[0] = 0; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0]; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 1; + pdsch_pdu_rel15->dmrsConfigType = gNB_mac->sched_ctrlCommon->active_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 = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->rbStart; + pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->rbSize; + pdsch_pdu_rel15->VRBtoPRBMapping = 0; + pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx); + pdsch_pdu_rel15->TBSize[0] = TBS; + pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->mcsTableIdx; + pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; + + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->StartSymbolIndex+pdsch_pdu_rel15->NrOfSymbols); + + LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos); + + /* Fill PDCCH DL DCI PDU */ + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci]; + pdcch_pdu_rel15->numDlDci++; + dci_pdu->RNTI = SI_RNTI; + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + dci_pdu->AggregationLevel = gNB_mac->sched_ctrlCommon->aggregation_level; + dci_pdu->CceIndex = gNB_mac->sched_ctrlCommon->cce_index; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + /* DCI payload */ + dci_pdu_rel15_t dci_payload; + memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); + + dci_payload.bwp_indicator.val = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id; + + // frequency domain assignment + dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0( + pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs); + + dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation; + dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs; + dci_payload.rv = pdsch_pdu_rel15->rvIndex[0]; + dci_payload.harq_pid = 0; + dci_payload.ndi = 0; + dci_payload.dai[0].val = 0; + dci_payload.tpc = 0; // table 7.2.1-1 in 38.213 + dci_payload.pucch_resource_indicator = 0; + dci_payload.pdsch_to_harq_feedback_timing_indicator.val = 0; + dci_payload.antenna_ports.val = 0; + dci_payload.dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; + + int dci_format = NR_DL_DCI_FORMAT_1_0; + int rnti_type = NR_RNTI_SI; + + fill_dci_pdu_rel15(scc, + secondaryCellGroup, + &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], + &dci_payload, + dci_format, + rnti_type, + pdsch_pdu_rel15->BWPSize, + gNB_mac->sched_ctrlCommon->active_bwp->bwp_Id); + + LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); + LOG_D(MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart); + LOG_D(MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing); + LOG_D(MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix); + LOG_D(MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex); + LOG_D(MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols); + for(int n=0;n<6;n++) LOG_D(MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]); + LOG_D(MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType); + LOG_D(MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize); + LOG_D(MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize); + LOG_D(MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType); + LOG_D(MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex); + LOG_D(MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity); + LOG_D(MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci); + +} + +void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { + + LOG_D(MAC,"Schedule_nr_sib1: frameP = %i, slotP = %i\n", frameP, slotP); + + // TODO: Get these values from RRC + const int CC_id = 0; + int time_domain_allocation = 0; + uint8_t mcsTableIdx = 0; + uint8_t mcs = 6; + + gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; + + if( (frameP%2 == gNB_mac->type0_PDCCH_CSS_config.sfn_c) && (slotP == gNB_mac->type0_PDCCH_CSS_config.n_0) && (gNB_mac->type0_PDCCH_CSS_config.num_rbs > 0) ) { + + LOG_D(MAC,"> SIB1 transmission\n"); + + // Get SIB1 + uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8]; + uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload); + LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length); + LOG_D(MAC,"SIB1: \n"); + for (int i=0;isched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + + // Calculate number of PRB_DMRS + uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6; + uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols); + uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); + + const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), + nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx), + gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3; + + nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; + nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols); + + const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; + + // Data to be transmitted + bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES); + memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length); + + tx_req->PDU_length = TBS; + tx_req->PDU_index = gNB_mac->pdu_index[0]++; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = TBS + 2; + gNB_mac->TX_req[CC_id].Number_of_PDUs++; + gNB_mac->TX_req[CC_id].SFN = frameP; + gNB_mac->TX_req[CC_id].Slot = slotP; + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index b31eee48f7..4d491b2843 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -38,7 +38,6 @@ #include "NR_MAC_COMMON/nr_mac.h" #include "NR_MAC_gNB/nr_mac_gNB.h" #include "NR_MAC_COMMON/nr_mac_extern.h" -#include "LAYER2/MAC/mac.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" /*NFAPI*/ @@ -57,27 +56,22 @@ #define WORD 32 //#define SIZE_OF_POINTER sizeof (void *) -int nr_generate_dlsch_pdu(module_id_t module_idP, - NR_UE_sched_ctrl_t *ue_sched_ctl, - unsigned char *sdus_payload, +// Compute and write all MAC CEs and subheaders, and return number of written +// bytes +int nr_write_ce_dlsch_pdu(module_id_t module_idP, + const NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *mac_pdu, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, unsigned char drx_cmd, - unsigned char *ue_cont_res_id, - unsigned short post_padding) { + unsigned char *ue_cont_res_id) +{ gNB_MAC_INST *gNB = RC.nrmac[module_idP]; NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; - unsigned char *dlsch_buffer_ptr = sdus_payload; uint8_t last_size = 0; int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0; // MAC CEs uint8_t mac_header_control_elements[16], *ce_ptr; ce_ptr = &mac_header_control_elements[0]; - // 1) Compute MAC CE and related subheaders - // DRX command subheader (MAC CE size 0) if (drx_cmd != 255) { mac_pdu_ptr->R = 0; @@ -302,41 +296,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, } } - // 2) Generation of DLSCH MAC subPDUs including subheaders and MAC SDUs - for (i = 0; i < num_sdus; i++) { - LOG_D(MAC, "[gNB] Generate DLSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]); - - if (sdu_lengths[i] < 128) { - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; - last_size = 2; - } else { - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; - last_size = 3; - } - - mac_pdu_ptr += last_size; - // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in - memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]); - dlsch_buffer_ptr += sdu_lengths[i]; - mac_pdu_ptr += sdu_lengths[i]; - } - - // 4) Compute final offset for padding - if (post_padding > 0) { - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING; - mac_pdu_ptr++; - } else { - // no MAC subPDU with padding - } - // compute final offset offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu)); @@ -372,116 +331,236 @@ uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) { } } -void nr_simple_dlsch_preprocessor(module_id_t module_id, - frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd) { +void nr_store_dlsch_buffer(module_id_t module_id, + frame_t frame, + sub_frame_t slot) { + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; - AssertFatal(UE_info->num_UEs <= 1, - "%s() cannot handle more than one UE, but found %d\n", - __func__, - UE_info->num_UEs); - if (UE_info->num_UEs == 0) - return; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - const int UE_id = 0; - const int CC_id = 0; - - NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - sched_ctrl->rbSize = 0; - - /* Retrieve amount of data to send for this UE */ - sched_ctrl->num_total_bytes = 0; - const int lcid = DL_SCH_LCID_DTCH; - const uint16_t rnti = UE_info->rnti[UE_id]; - sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, - rnti, - module_id, - frame, - slot, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - 0, - 0); - sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; - if (sched_ctrl->num_total_bytes == 0 && !get_softmodem_params()->phy_test) - return; - LOG_D(MAC, - "%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n", - frame, - slot, - lcid, - sched_ctrl->rlc_status[lcid].bytes_in_buffer); - - /* Find a free CCE */ - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); - uint8_t nr_of_candidates; - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space); - sched_ctrl->coreset = get_coreset( - sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); - sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], - sched_ctrl->active_bwp, - sched_ctrl->coreset, - sched_ctrl->aggregation_level, - UE_info->rnti[UE_id], - 0); // m - if (sched_ctrl->cce_index < 0) { - LOG_E(MAC, "%s(): could not find CCE for UE %d\n", __func__, UE_id); - return; + sched_ctrl->num_total_bytes = 0; + const int lcid = DL_SCH_LCID_DTCH; + const uint16_t rnti = UE_info->rnti[UE_id]; + sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, + rnti, + module_id, + frame, + slot, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + 0, + 0); + sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; + LOG_D(MAC, + "[%s][%d.%d], DTCH%d->DLSCH, RLC status %d bytes TA %d\n", + __func__, + frame, + slot, + lcid, + sched_ctrl->rlc_status[lcid].bytes_in_buffer, + sched_ctrl->ta_apply); } +} - /* Find PUCCH occasion */ - nr_acknack_scheduling(module_id, - UE_id, - frame, - slot, - num_slots_per_tdd, - &sched_ctrl->pucch_sched_idx, - &sched_ctrl->pucch_occ_idx); - - AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n"); - - uint8_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; - const int current_harq_pid = sched_ctrl->current_harq_pid; - NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; +bool allocate_retransmission(module_id_t module_id, + uint8_t *rballoc_mask, + int *n_rb_sched, + int UE_id, + int current_harq_pid){ + NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id]; NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; - const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275); - int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275); + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - if (harq->round != 0) { /* retransmission */ - sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation; + sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation; - /* ensure that there is a free place for RB allocation */ - int rbSize = 0; - while (rbSize < retInfo->rbSize) { - rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ - rbSize = 0; - while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++; - if (rbStart >= bwpSize) { - LOG_E(MAC, - "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", + /* ensure that there is a free place for RB allocation */ + int rbSize = 0; + while (rbSize < retInfo->rbSize) { + rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ + rbSize = 0; + while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; + if (rbStart >= bwpSize) { + LOG_D(MAC, + "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", + UE_id, + RC.nrmac[module_id]->UE_info.rnti[UE_id]); + return false; + } + while (rbStart + rbSize < bwpSize + && rballoc_mask[rbStart + rbSize] + && rbSize < retInfo->rbSize) + rbSize++; + } + sched_ctrl->rbSize = retInfo->rbSize; + sched_ctrl->rbStart = rbStart; + + /* MCS etc: just reuse from previous scheduling opportunity */ + sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx; + sched_ctrl->mcs = retInfo->mcs; + sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData; + + /* retransmissions: directly allocate */ + *n_rb_sched -= sched_ctrl->rbSize; + for (int rb = 0; rb < sched_ctrl->rbSize; rb++) + rballoc_mask[rb+sched_ctrl->rbStart] = 0; + return true; +} + +float thr_ue[MAX_MOBILES_PER_GNB]; + +void pf_dl(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + NR_list_t *UE_list, + int n_rb_sched, + uint8_t *rballoc_mask, + int max_num_ue) { + + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + float coeff_ue[MAX_MOBILES_PER_GNB]; + // UEs that could be scheduled + int ue_array[MAX_MOBILES_PER_GNB]; + NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB }; + + /* Loop UE_info->list to check retransmission */ + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific); + sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ + sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; + const rnti_t rnti = UE_info->rnti[UE_id]; + + /* Calculate Throughput */ + const float a = 0.0005f; // corresponds to 200ms window + const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes; + thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b; + + /* retransmission */ + if (sched_ctrl->dl_harq_pid >= 0) { + /* Find a free CCE */ + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE){ + LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti); + continue; + } + /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH + * allocation after CCE alloc fail would be more complex) */ + const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot); + if (!alloc) { + LOG_W(MAC, + "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", + __func__, UE_id, - rnti); + rnti, + frame, + slot); + int cid = sched_ctrl->coreset->controlResourceSetId; + UE_info->num_pdcch_cand[UE_id][cid]--; + int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid]; + for (int i = 0; i < sched_ctrl->aggregation_level; i++) + cce_list[sched_ctrl->cce_index + i] = 0; return; } - while (rbStart + rbSize < bwpSize - && !vrb_map[rbStart + rbSize] - && rbSize < retInfo->rbSize) - rbSize++; - } - sched_ctrl->rbSize = retInfo->rbSize; - sched_ctrl->rbStart = rbStart; + /* Allocate retransmission */ + bool r = allocate_retransmission(module_id, rballoc_mask, &n_rb_sched, UE_id, sched_ctrl->dl_harq_pid); + if (!r) { + LOG_D(MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot); + continue; + } + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ + max_num_ue--; + if (max_num_ue < 0) return; + } else { + /* Check DL buffer and skip this UE if no bytes and no TA necessary */ + if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024) + continue; - /* MCS etc: just reuse from previous scheduling opportunity */ - sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx; - sched_ctrl->mcs = retInfo->mcs; - sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData; - } else { + /* Calculate coeff */ + sched_ctrl->time_domain_allocation = 2; + sched_ctrl->mcsTableIdx = 0; + sched_ctrl->mcs = 9; + sched_ctrl->numDmrsCdmGrpsNoData = 1; + uint8_t N_PRB_DMRS = + getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); + int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, + sched_ctrl->time_domain_allocation); + uint32_t tbs = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + 1, // rbSize + nrOfSymbols, + N_PRB_DMRS, // FIXME // This should be multiplied by the + // number of dmrs symbols + 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id]; + LOG_D(MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", + b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]); + /* Create UE_sched list for UEs eligible for new transmission*/ + add_tail_nr_list(&UE_sched, UE_id); + } + } + + /* Loop UE_sched to find max coeff and allocate transmission */ + while (max_num_ue > 0 && n_rb_sched > 0 && UE_sched.head >= 0) { + + /* Find max coeff from UE_sched*/ + int *max = &UE_sched.head; /* assume head is max */ + int *p = &UE_sched.next[*max]; + while (*p >= 0) { + /* if the current one has larger coeff, save for later */ + if (coeff_ue[*p] > coeff_ue[*max]) + max = p; + p = &UE_sched.next[*p]; + } + /* remove the max one: do not use remove_nr_list() it goes through the + * whole list every time. Note that UE_sched.tail might not be set + * correctly anymore */ + const int UE_id = *max; + p = &UE_sched.next[*max]; + *max = UE_sched.next[*max]; + *p = -1; + + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const uint16_t rnti = UE_info->rnti[UE_id]; + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + /* Find a free CCE */ + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE) { + LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, UE_id, rnti); + continue; + } + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ + max_num_ue--; + if (max_num_ue < 0) return; + + /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH + * allocation after CCE alloc fail would be more complex) */ + const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot); + if (!alloc) { + LOG_W(MAC, + "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", + __func__, + UE_id, + rnti, + frame, + slot); + int cid = sched_ctrl->coreset->controlResourceSetId; + UE_info->num_pdcch_cand[UE_id][cid]--; + int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid]; + for (int i = 0; i < sched_ctrl->aggregation_level; i++) + cce_list[sched_ctrl->cce_index + i] = 0; + return; + } + + /* Allocate transmission */ // Time-domain allocation sched_ctrl->time_domain_allocation = 2; @@ -491,53 +570,112 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id, sched_ctrl->numDmrsCdmGrpsNoData = 1; // Freq-demain allocation - while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++; + while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; - uint8_t N_PRB_DMRS = + const uint8_t N_PRB_DMRS = getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); - int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, - sched_ctrl->time_domain_allocation); + const int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, + sched_ctrl->time_domain_allocation); + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon; + const uint8_t N_DMRS_SLOT = get_num_dmrs_symbols( + sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, + scc->dmrs_TypeA_Position, + nrOfSymbols); int rbSize = 0; uint32_t TBS = 0; + const int oh = 2 + (sched_ctrl->num_total_bytes >= 256) + + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024); do { rbSize++; TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), rbSize, nrOfSymbols, - N_PRB_DMRS, // FIXME // This should be multiplied by the - // number of dmrs symbols + N_PRB_DMRS * N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, 1 /* nrOfLayers */) >> 3; - } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes); + } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh); sched_ctrl->rbSize = rbSize; sched_ctrl->rbStart = rbStart; + + /* transmissions: directly allocate */ + n_rb_sched -= sched_ctrl->rbSize; + for (int rb = 0; rb < sched_ctrl->rbSize; rb++) + rballoc_mask[rb+sched_ctrl->rbStart] = 0; + } +} + +void nr_simple_dlsch_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot) { + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + + if (UE_info->num_UEs == 0) + return; + + const int CC_id = 0; + + + /* Get bwpSize from the first UE */ + int UE_id = UE_info->list.head; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + uint8_t rballoc_mask[bwpSize]; + int n_rb_sched = 0; + for (int i = 0; i < bwpSize; i++) { + // calculate mask: init with "NOT" vrb_map: + // if any RB in vrb_map is blocked (1), the current RBG will be 0 + rballoc_mask[i] = !vrb_map[i]; + n_rb_sched += rballoc_mask[i]; } - /* mark the corresponding RBs as used */ - for (int rb = 0; rb < sched_ctrl->rbSize; rb++) - vrb_map[rb + sched_ctrl->rbStart] = 1; + /* Retrieve amount of data to send for this UE */ + nr_store_dlsch_buffer(module_id, frame, slot); + + /* proportional fair scheduling algorithm */ + pf_dl(module_id, + frame, + slot, + &UE_info->list, + n_rb_sched, + rballoc_mask, + 2); } void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd) { - /* PREPROCESSOR */ - nr_simple_dlsch_preprocessor(module_id, frame, slot, num_slots_per_tdd); - + sub_frame_t slot) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; - NR_UE_info_t *UE_info = &gNB_mac->UE_info; + + /* PREPROCESSOR */ + gNB_mac->pre_processor_dl(module_id, frame, slot); const int CC_id = 0; + NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon; + NR_UE_info_t *UE_info = &gNB_mac->UE_info; - NR_UE_list_t *UE_list = &UE_info->list; + nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; + + NR_list_t *UE_list = &UE_info->list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - if (sched_ctrl->rbSize <= 0 && !get_softmodem_params()->phy_test) + UE_info->mac_stats[UE_id].dlsch_current_bytes = 0; + + /* update TA and set ta_apply every 10 frames. + * Possible improvement: take the periodicity from input file. + * If such UE is not scheduled now, it will be by the preprocessor later. + * If we add the CE, ta_apply will be reset */ + if (frame == (sched_ctrl->ta_frame + 10) % 1024){ + sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */ + LOG_D(MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot); + } + + if (sched_ctrl->rbSize <= 0) continue; const rnti_t rnti = UE_info->rnti[UE_id]; @@ -557,51 +695,243 @@ void nr_schedule_ue_spec(module_id_t module_id, uint8_t N_PRB_DMRS = getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); + uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, + RC.nrmac[module_id]->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position , + nrOfSymbols); + const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(sched_ctrl->active_bwp); + const int nrOfLayers = 1; + const uint16_t R = nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx); + const uint8_t Qm = nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx); const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), sched_ctrl->rbSize, nrOfSymbols, - N_PRB_DMRS, // FIXME // This should be multiplied by the - // number of dmrs symbols + N_PRB_DMRS * N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - 1 /* nrOfLayers */) + nrOfLayers) >> 3; - const int current_harq_pid = sched_ctrl->current_harq_pid; + int8_t current_harq_pid = sched_ctrl->dl_harq_pid; + if (current_harq_pid < 0) { + /* PP has not selected a specific HARQ Process, get a new one */ + current_harq_pid = sched_ctrl->available_dl_harq.head; + AssertFatal(current_harq_pid >= 0, + "no free HARQ process available for UE %d\n", + UE_id); + remove_front_nr_list(&sched_ctrl->available_dl_harq); + sched_ctrl->dl_harq_pid = current_harq_pid; + } else { + /* PP selected a specific HARQ process. Check whether it will be a new + * transmission or a retransmission, and remove from the corresponding + * list */ + if (sched_ctrl->harq_processes[current_harq_pid].round == 0) + remove_nr_list(&sched_ctrl->available_dl_harq, current_harq_pid); + else + remove_nr_list(&sched_ctrl->retrans_dl_harq, current_harq_pid); + } NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; - NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx][sched_ctrl->pucch_occ_idx]; + DevAssert(!harq->is_waiting); + add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid); + NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; harq->feedback_slot = pucch->ul_slot; - harq->is_waiting = 1; + harq->is_waiting = true; UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++; - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; - nr_fill_nfapi_dl_pdu(module_id, - UE_id, - sched_ctrl->active_bwp->bwp_Id, - sched_ctrl->search_space, - sched_ctrl->coreset, - dl_req, - pucch, - 1 /* nrOfLayers */, - sched_ctrl->mcs, - sched_ctrl->rbSize, - sched_ctrl->rbStart, - sched_ctrl->numDmrsCdmGrpsNoData, - getDmrsConfigType(sched_ctrl->active_bwp), - sched_ctrl->mcsTableIdx, - nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), - TBS, - sched_ctrl->time_domain_allocation, - startSymbolIndex, - nrOfSymbols, - sched_ctrl->aggregation_level, - sched_ctrl->cce_index, - current_harq_pid, - harq->ndi, - harq->round); + LOG_D(MAC, + "%4d.%2d RNTI %04x start %d RBs %d startSymbol %d nb_symbsol %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", + frame, + slot, + rnti, + sched_ctrl->rbStart, + sched_ctrl->rbSize, + startSymbolIndex, + nrOfSymbols, + sched_ctrl->mcs, + TBS, + current_harq_pid, + harq->round, + harq->ndi); + + NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp; + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList, + "searchSpacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0, + "searchSPacesToAddModList is empty\n"); + + /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not + * exist, create it */ + const int bwpid = sched_ctrl->active_bwp->bwp_Id; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid]; + if (!pdcch_pdu) { + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset(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_req->nPDUs += 1; + pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nr_configure_pdcch(pdcch_pdu, sched_ctrl->search_space, sched_ctrl->coreset, scc, bwp); + gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu; + } + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset(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)); + dl_req->nPDUs += 1; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + pdsch_pdu->pduBitmap = 0; + pdsch_pdu->rnti = rnti; + /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control + * message. This is used to associate control information to data and is + * reset every slot. */ + const int pduindex = gNB_mac->pdu_index[CC_id]++; + pdsch_pdu->pduIndex = pduindex; + + // BWP + pdsch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); + pdsch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; + if (bwp->bwp_Common->genericParameters.cyclicPrefix) + pdsch_pdu->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix; + else + pdsch_pdu->CyclicPrefix = 0; + + // Codeword information + pdsch_pdu->NrOfCodewords = 1; + pdsch_pdu->targetCodeRate[0] = R; + pdsch_pdu->qamModOrder[0] = Qm; + pdsch_pdu->mcsIndex[0] = sched_ctrl->mcs; + pdsch_pdu->mcsTable[0] = sched_ctrl->mcsTableIdx; + pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round]; + pdsch_pdu->TBSize[0] = TBS; + + pdsch_pdu->dataScramblingId = *scc->physCellId; + pdsch_pdu->nrOfLayers = nrOfLayers; + pdsch_pdu->transmissionScheme = 0; + pdsch_pdu->refPoint = 0; // Point A + + // DMRS + pdsch_pdu->dlDmrsSymbPos = + fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, + scc->dmrs_TypeA_Position, + nrOfSymbols); + pdsch_pdu->dmrsConfigType = dmrsConfigType; + pdsch_pdu->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu->SCID = 0; + pdsch_pdu->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; + pdsch_pdu->dmrsPorts = 1; + + // Pdsch Allocation in frequency domain + pdsch_pdu->resourceAlloc = 1; + pdsch_pdu->rbStart = sched_ctrl->rbStart; + pdsch_pdu->rbSize = sched_ctrl->rbSize; + pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP + + // Resource Allocation in time domain + pdsch_pdu->StartSymbolIndex = startSymbolIndex; + pdsch_pdu->NrOfSymbols = nrOfSymbols; + + /* Check and validate PTRS values */ + struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS = + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS; + if (phaseTrackingRS) { + bool valid_ptrs_setup = set_dl_ptrs_values(phaseTrackingRS->choice.setup, + pdsch_pdu->rbSize, + pdsch_pdu->mcsIndex[0], + pdsch_pdu->mcsTable[0], + &pdsch_pdu->PTRSFreqDensity, + &pdsch_pdu->PTRSTimeDensity, + &pdsch_pdu->PTRSPortIndex, + &pdsch_pdu->nEpreRatioOfPDSCHToPTRS, + &pdsch_pdu->PTRSReOffset, + pdsch_pdu->NrOfSymbols); + if (valid_ptrs_setup) + pdsch_pdu->pduBitmap |= 0x1; // Bit 0: pdschPtrs - Indicates PTRS included (FR2) + } + + /* Fill PDCCH DL DCI PDU */ + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci]; + pdcch_pdu->numDlDci++; + dci_pdu->RNTI = rnti; + if (sched_ctrl->coreset->pdcch_DMRS_ScramblingID && + sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { + dci_pdu->ScramblingId = *sched_ctrl->coreset->pdcch_DMRS_ScramblingID; + dci_pdu->ScramblingRNTI = rnti; + } else { + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + } + dci_pdu->AggregationLevel = sched_ctrl->aggregation_level; + dci_pdu->CceIndex = sched_ctrl->cce_index; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + /* DCI payload */ + dci_pdu_rel15_t dci_payload; + memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); + // bwp indicator + const int n_dl_bwp = UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; + AssertFatal(n_dl_bwp == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + n_dl_bwp); + // as per table 7.3.1.1.2-1 in 38.212 + dci_payload.bwp_indicator.val = n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1; + AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); + dci_payload.frequency_domain_assignment.val = + PRBalloc_to_locationandbandwidth0( + pdsch_pdu->rbSize, + pdsch_pdu->rbStart, + pdsch_pdu->BWPSize); + dci_payload.time_domain_assignment.val = sched_ctrl->time_domain_allocation; + dci_payload.mcs = sched_ctrl->mcs; + dci_payload.rv = pdsch_pdu->rvIndex[0]; + dci_payload.harq_pid = current_harq_pid; + dci_payload.ndi = harq->ndi; + dci_payload.dai[0].val = (pucch->dai_c-1)&3; + dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213 + dci_payload.pucch_resource_indicator = pucch->resource_indicator; + dci_payload.pdsch_to_harq_feedback_timing_indicator.val = pucch->timing_indicator; // PDSCH to HARQ TI + dci_payload.antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 + dci_payload.dmrs_sequence_initialization.val = pdsch_pdu->SCID; + LOG_D(MAC, + "%4d.%2d 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", + frame, + slot, + dci_payload.frequency_domain_assignment.val, + pdsch_pdu->rbStart, + pdsch_pdu->rbSize, + pdsch_pdu->BWPSize, + dci_payload.time_domain_assignment.val, + dci_payload.vrb_to_prb_mapping.val, + dci_payload.mcs, + dci_payload.tb_scaling, + dci_payload.ndi, + dci_payload.rv); + + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0; + const int rnti_type = NR_RNTI_C; + + fill_dci_pdu_rel15(scc, + UE_info->secondaryCellGroup[UE_id], + dci_pdu, + &dci_payload, + dci_format, + rnti_type, + pdsch_pdu->BWPSize, + bwp->bwp_Id); + + LOG_D(MAC, + "coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + (unsigned long long)pdcch_pdu->FreqDomainResource, + pdcch_pdu->StartSymbolIndex, + pdcch_pdu->DurationSymbols); NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; if (harq->round != 0) { /* retransmission */ @@ -627,113 +957,132 @@ void nr_schedule_ue_spec(module_id_t module_id, retInfo->mcs, retInfo->numDmrsCdmGrpsNoData); /* we do not have to do anything, since we do not require to get data - * from RLC, encode MAC CEs, or copy data to FAPI structures */ - LOG_W(MAC, "%d.%2d retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti); + * from RLC or encode MAC CEs. The TX_req structure is filled below + * or copy data to FAPI structures */ + LOG_D(MAC, + "%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n", + frame, + slot, + UE_id, + rnti, + current_harq_pid, + harq->round, + harq->ndi); + AssertFatal(harq->tb_size == TBS, + "UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n", + UE_id, + current_harq_pid); } else { /* initial transmission */ - /* reserve space for timing advance of UE if necessary, - * nr_generate_dlsch_pdu() checks for ta_apply and add TA CE if necessary */ - const int ta_len = (sched_ctrl->ta_apply) ? 2 : 0; + LOG_D(MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot); + + harq->tb_size = TBS; + uint8_t *buf = (uint8_t *) harq->tb; + + /* first, write all CEs that might be there */ + int written = nr_write_ce_dlsch_pdu(module_id, + sched_ctrl, + (unsigned char *)buf, + 255, // no drx + NULL); // contention res id + buf += written; + int size = TBS - written; + DevAssert(size >= 0); + + /* next, get RLC data */ - /* Get RLC data TODO: remove random data retrieval */ - int header_length_total = 0; - int header_length_last = 0; - int sdu_length_total = 0; - int num_sdus = 0; - uint16_t sdu_lengths[NB_RB_MAX] = {0}; - uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES]; - unsigned char sdu_lcids[NB_RB_MAX] = {0}; const int lcid = DL_SCH_LCID_DTCH; + int dlsch_total_bytes = 0; if (sched_ctrl->num_total_bytes > 0) { - LOG_D(MAC, - "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting " - "%d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", - module_id, - frame, - TBS - ta_len - header_length_total - sdu_length_total - 3, - lcid, - header_length_total, - TBS); + tbs_size_t len = 0; + while (size > 3) { + // we do not know how much data we will get from RLC, i.e., whether it + // will be longer than 256B or not. Therefore, reserve space for long header, then + // fetch data, then fill real length + NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; + buf += 3; + size -= 3; - sdu_lengths[num_sdus] = mac_rlc_data_req(module_id, - rnti, - module_id, - frame, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3, - (char *)&mac_sdus[sdu_length_total], - 0, - 0); + /* limit requested number of bytes to what preprocessor specified, or + * such that TBS is full */ + const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer, size); + len = mac_rlc_data_req(module_id, + rnti, + module_id, + frame, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + ndata, + (char *)buf, + 0, + 0); - LOG_D(MAC, - "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_id, - sdu_lengths[num_sdus], - lcid); + LOG_D(MAC, + "%4d.%2d RNTI %04x: %d bytes from DTCH %d (ndata %d, remaining size %d)\n", + frame, + slot, + rnti, + len, + lcid, + ndata, + size); + if (len == 0) + break; - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); - header_length_total += header_length_last; - - num_sdus++; - - //ue_sched_ctl->uplane_inactivity_timer = 0; + header->R = 0; + header->F = 1; + header->LCID = lcid; + header->L1 = (len >> 8) & 0xff; + header->L2 = len & 0xff; + size -= len; + buf += len; + dlsch_total_bytes += len; + } + if (len == 0) { + /* RLC did not have data anymore, mark buffer as unused */ + buf -= 3; + size += 3; + } } - else if (get_softmodem_params()->phy_test) { - LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot); + else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) { + /* we will need the large header, phy-test typically allocates all + * resources and fills to the last byte below */ + NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf; + buf += 3; + size -= 3; + DevAssert(size > 0); + LOG_D(MAC, "Configuring DL_TX in %d.%d: TBS %d with %d B of random data\n", frame, slot, TBS, size); // fill dlsch_buffer with random data - for (int i = 0; i < TBS; i++) - mac_sdus[i] = (unsigned char) (lrand48()&0xff); - sdu_lcids[0] = 0x3f; // DRB - sdu_lengths[0] = TBS - ta_len - 3; - header_length_total += 2 + (sdu_lengths[0] >= 128); - sdu_length_total += sdu_lengths[0]; - num_sdus +=1; + for (int i = 0; i < size; i++) + buf[i] = lrand48() & 0xff; + header->R = 0; + header->F = 1; + header->LCID = DL_SCH_LCID_PADDING; + header->L1 = (size >> 8) & 0xff; + header->L2 = size & 0xff; + size -= size; + buf += size; + dlsch_total_bytes += size; + } + + // Add padding header and zero rest out if there is space left + if (size > 0) { + NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) buf; + padding->R = 0; + padding->LCID = DL_SCH_LCID_PADDING; + size -= 1; + buf += 1; + while (size > 0) { + *buf = 0; + buf += 1; + size -= 1; + } } UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; - UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total; - - // Check if there is data from RLC or CE - const int post_padding = TBS >= 2 + header_length_total + sdu_length_total + ta_len; - // padding param currently not in use - //padding = TBS - header_length_total - sdu_length_total - ta_len - 1; - - const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; - nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; - /* pointer to directly generate the PDU into the nFAPI structure */ - uint32_t *buf = tx_req->TLVs[0].value.direct; - - const int offset = nr_generate_dlsch_pdu( - module_id, - sched_ctrl, - (unsigned char *)mac_sdus, - (unsigned char *)buf, - num_sdus, // num_sdus - sdu_lengths, - sdu_lcids, - 255, // no drx - NULL, // contention res id - post_padding); - - // Padding: fill remainder of DLSCH with 0 - if (post_padding > 0) { - for (int j = 0; j < TBS - offset; j++) - buf[offset + j] = 0; - } - - /* the buffer has been filled by nr_generate_dlsch_pdu(), below we simply - * fill the remaining information */ - tx_req->PDU_length = TBS; - tx_req->PDU_index = gNB_mac->pdu_index[0]++; - tx_req->num_TLV = 1; - tx_req->TLVs[0].length = TBS + 2; - gNB_mac->TX_req[CC_id].Number_of_PDUs++; - gNB_mac->TX_req[CC_id].SFN = frame; - gNB_mac->TX_req[CC_id].Slot = slot; + UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS; + UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes; retInfo->rbSize = sched_ctrl->rbSize; retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation; @@ -741,17 +1090,33 @@ void nr_schedule_ue_spec(module_id_t module_id, retInfo->mcs = sched_ctrl->mcs; retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - if (frame%100 == 0) { - LOG_I(MAC, - "%d.%d, first 10 payload bytes, TBS size: %d \n", + // ta command is sent, values are reset + if (sched_ctrl->ta_apply) { + sched_ctrl->ta_apply = false; + sched_ctrl->ta_frame = frame; + LOG_D(MAC, + "%d.%2d UE %d TA scheduled, resetting TA frame\n", frame, slot, - TBS); - for(int i = 0; i < 10; i++) - LOG_I(MAC, "byte %d: %x\n", i, ((uint8_t *) buf)[i]); + UE_id); } -#endif + + T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti), + T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->tb, TBS)); } + + const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; + tx_req->PDU_length = TBS; + tx_req->PDU_index = pduindex; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = TBS + 2; + memcpy(tx_req->TLVs[0].value.direct, harq->tb, TBS); + gNB_mac->TX_req[CC_id].Number_of_PDUs++; + gNB_mac->TX_req[CC_id].SFN = frame; + gNB_mac->TX_req[CC_id].Slot = slot; + + /* mark UE as scheduled */ + sched_ctrl->rbSize = 0; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index cb4cb0ba93..8dbe8728f3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -80,7 +80,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon; - int dlBWP_carrier_bandwidth = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275); + int dlBWP_carrier_bandwidth = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); /* @@ -94,7 +94,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, for (CC_id=0; CC_iddownlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,275)); + NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE)); dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; @@ -117,8 +117,8 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, pdsch_pdu_rel15->pduIndex = 0; // 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->BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pdsch_pdu_rel15->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; @@ -252,907 +252,256 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } -int configure_fapi_dl_pdu_phytest(int Mod_idP, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - uint8_t *mcsIndex, - uint16_t *rbSize, - uint16_t *rbStart) { - gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; - NR_COMMON_channels_t *cc = nr_mac->common_channels; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - - 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_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; - AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); - - 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_info->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; - int current_harq_pid = UE_info->UE_sched_ctrl[UE_id].current_harq_pid; - pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0); - pdsch_pdu_rel15->qamModOrder[0] = 2; - pdsch_pdu_rel15->mcsIndex[0] = mcs; - pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]; - pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; - pdsch_pdu_rel15->nrOfLayers = 1; - pdsch_pdu_rel15->transmissionScheme = 0; - pdsch_pdu_rel15->refPoint = 0; // Point A - UE_info->mac_stats[UE_id].dlsch_rounds[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++; - pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; - pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; - pdsch_pdu_rel15->SCID = 0; - 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 - - 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 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t)); - - // bwp indicator - int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; - if (n_dl_bwp < 4) - dci_pdu_rel15[0].bwp_indicator.val = bwp_id; - else - dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 - // frequency domain assignment - if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) - dci_pdu_rel15[0].frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart, - NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275)); - else - AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - // time domain assignment - dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV; - // mcs and rv - dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; - dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; - // harq pid and ndi - dci_pdu_rel15[0].harq_pid = current_harq_pid; - dci_pdu_rel15[0].ndi = UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi; - // DAI - dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3; - // TPC for PUCCH - dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 - // PUCCH resource indicator - dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; - // PDSCH to HARQ TI - dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator; - UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot; - UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1; - // antenna ports - dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 - // dmrs sequence initialization - dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; - LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - dci_pdu_rel15[0].frequency_domain_assignment.val, - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), - dci_pdu_rel15[0].time_domain_assignment.val, - dci_pdu_rel15[0].vrb_to_prb_mapping.val, - dci_pdu_rel15[0].mcs, - dci_pdu_rel15[0].tb_scaling, - dci_pdu_rel15[0].ndi, - dci_pdu_rel15[0].rv); - - NR_SearchSpace_t *ss; - int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - - 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"); - - int found=0; - - 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->searchSpaceType->present == target_ss) { - found=1; - break; +/* schedules whole bandwidth for first user, all the time */ +void nr_preprocessor_phytest(module_id_t module_id, + frame_t frame, + sub_frame_t slot) +{ + if (slot != 1) + return; + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + const int UE_id = 0; + const int CC_id = 0; + AssertFatal(UE_info->active[UE_id], + "%s(): expected UE %d to be active\n", + __func__, + UE_id); + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + /* find largest unallocated chunk */ + const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int rbStart = 0; + int tStart = 0; + int rbSize = 0; + uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + /* find largest unallocated RB region */ + do { + /* advance to first free RB */ + while (tStart < bwpSize && vrb_map[tStart]) + tStart++; + /* find maximum rbSize at current rbStart */ + int tSize = 1; + while (tStart + tSize < bwpSize && !vrb_map[tStart + tSize]) + tSize++; + if (tSize > rbSize) { + rbStart = tStart; + rbSize = tSize; } - } - AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); + tStart += tSize; + } while (tStart < bwpSize); - uint8_t nr_of_candidates, aggregation_level; - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); - NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */); - int CCEIndex = allocate_nr_CCEs( - nr_mac, - bwp, - coreset, - aggregation_level, - UE_info->rnti[UE_id], - 0); // m - if (CCEIndex < 0) { - LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PDSCH\n", __func__); - free(dci_pdu_rel15); - return 0; - } - nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_info->rnti[UE_id], - ss, - coreset, - scc, - bwp, - aggregation_level, - CCEIndex); + sched_ctrl->num_total_bytes = 0; + const int lcid = DL_SCH_LCID_DTCH; + const uint16_t rnti = UE_info->rnti[UE_id]; + /* update sched_ctrl->num_total_bytes so that postprocessor schedules data, + * if available */ + sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, + rnti, + module_id, + frame, + slot, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + 0, + 0); + sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; - int dci_formats[2]; - int rnti_types[2]; - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) - dci_formats[0] = NR_DL_DCI_FORMAT_1_1; - else - dci_formats[0] = NR_DL_DCI_FORMAT_1_0; + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + sched_ctrl->coreset = get_coreset( + sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + const int cid = sched_ctrl->coreset->controlResourceSetId; + const uint16_t Y = UE_info->Y[UE_id][cid][slot]; + const int m = UE_info->num_pdcch_cand[UE_id][cid]; + sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], + sched_ctrl->active_bwp, + sched_ctrl->coreset, + sched_ctrl->aggregation_level, + Y, + m, + nr_of_candidates); + AssertFatal(sched_ctrl->cce_index >= 0, + "%s(): could not find CCE for UE %d\n", + __func__, + UE_id); - rnti_types[0] = NR_RNTI_C; - - fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); - - LOG_D(MAC, "DCI params: rnti %x, rnti_type %d, dci_format %d\n \ - coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", - pdcch_pdu_rel15->dci_pdu.RNTI[0], - rnti_types[0], - dci_formats[0], - (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, - pdcch_pdu_rel15->StartSymbolIndex, - pdcch_pdu_rel15->DurationSymbols); - - int x_Overhead = 0; // should be 0 for initialBWP - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu,x_Overhead,pdsch_pdu_rel15->numDmrsCdmGrpsNoData,0); - - // Hardcode it for now - TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; - if (UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0) - UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; - - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", - pdsch_pdu_rel15->rbStart, - 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); - - free(dci_pdu_rel15); - return TBS; //Return TBS in bytes -} - -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, - int time_domain_assignment, uint8_t tpc, - int n_ubwp, int bwp_id) { - - switch(dci_formats[(pdcch_pdu_rel15->numDlDci)-1]) { - case NR_UL_DCI_FORMAT_0_0: - dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, - pusch_pdu->rb_start, - NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); - - dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; - dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; - 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 = 1; - break; - case NR_UL_DCI_FORMAT_0_1: - dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator; - dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index; - dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id; - dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; - dci_pdu_rel15->dai[0].val = 0; //TODO - // bwp indicator - if (n_ubwp < 4) - dci_pdu_rel15->bwp_indicator.val = bwp_id; - else - dci_pdu_rel15->bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 - // frequency domain assignment - if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) - dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, - pusch_pdu->rb_start, - NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); - else - AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - // time domain assignment - dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; - // mcs - dci_pdu_rel15->mcs = pusch_pdu->mcs_index; - // tpc command for pusch - dci_pdu_rel15->tpc = tpc; - // SRS resource indicator - if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) { - if (*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook) - dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS - else - AssertFatal(1==0,"Non Codebook configuration non supported\n"); - } - // Antenna Ports - dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank - // DMRS sequence initialization - dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; - break; - default : - AssertFatal(1==0,"Valid UL formats are 0_0 and 0_1 \n"); + const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot); + if (!alloc) { + LOG_D(MAC, + "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n", + __func__, + UE_id, + rnti, + frame, + slot); + UE_info->num_pdcch_cand[UE_id][cid]--; + int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid]; + for (int i = 0; i < sched_ctrl->aggregation_level; i++) + cce_list[sched_ctrl->cce_index + i] = 0; + return; } - 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->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci], - dci_pdu_rel15->frequency_domain_assignment.val, - dci_pdu_rel15->time_domain_assignment.val, - dci_pdu_rel15->frequency_hopping_flag.val, - dci_pdu_rel15->mcs, - dci_pdu_rel15->tpc, - dci_pdu_rel15->ndi, - dci_pdu_rel15->rv); - -} - - -void configure_fapi_dl_Tx(module_id_t Mod_idP, - frame_t frameP, - sub_frame_t slotP, - nfapi_nr_dl_tti_request_body_t *dl_req, - nfapi_nr_pdu_t *tx_req, - int tbs_bytes, - int16_t pdu_index){ - - int CC_id = 0; - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; - - LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS (bytes): %d\n", - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->StartSymbolIndex, - pdsch_pdu_rel15->NrOfSymbols, - pdsch_pdu_rel15->nrOfLayers, - pdsch_pdu_rel15->NrOfCodewords, - pdsch_pdu_rel15->mcsIndex[0], - tbs_bytes); - - 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 = tbs_bytes +2; - - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_info.DLSCH_pdu[0][0].payload[0], tbs_bytes); - - nr_mac->TX_req[CC_id].Number_of_PDUs++; - nr_mac->TX_req[CC_id].SFN = frameP; - nr_mac->TX_req[CC_id].Slot = slotP; -} - -void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - NR_sched_pucch *pucch_sched, - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ - - LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP); - - int post_padding = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int lcid, offset, i, header_length_last, TBS_bytes = 0; - int UE_id = 0, CC_id = 0; - - gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; - //NR_COMMON_channels_t *cc = nr_mac->common_channels; - //NR_ServingCellConfigCommon_t *scc=cc->ServingCellConfigCommon; - nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; - nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[gNB_mac->TX_req[CC_id].Number_of_PDUs]; - - mac_rlc_status_resp_t rlc_status; - - NR_UE_info_t *UE_info = &gNB_mac->UE_info; - - if (UE_info->num_UEs ==0) return; - - unsigned char sdu_lcids[NB_RB_MAX] = {0}; - uint16_t sdu_lengths[NB_RB_MAX] = {0}; - uint16_t rnti = UE_info->rnti[UE_id]; - NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; - - uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES]; - - LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n"); - - int ta_len = (ue_sched_ctl->ta_apply)?2:0; - - TBS_bytes = configure_fapi_dl_pdu_phytest( - module_idP, - dl_req, - pucch_sched, - dlsch_config != NULL ? dlsch_config->mcsIndex : NULL, - dlsch_config != NULL ? &dlsch_config->rbSize : NULL, - dlsch_config != NULL ? &dlsch_config->rbStart : NULL); - - if (TBS_bytes == 0) - return; - - lcid = DL_SCH_LCID_DTCH; - - //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - - // TODO: check if the lcid is active - - LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", - module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); - - //if (TBS_bytes - 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, - 0, - 0); - - if (rlc_status.bytes_in_buffer > 0) { - - LOG_I(MAC, "configure fapi due to data availability \n"); - - LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", - module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, - lcid, header_length_total, TBS_bytes); - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, - (char *)&mac_sdus[sdu_length_total], - 0, - 0); - - LOG_W(MAC, "[gNB %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++; - - //ue_sched_ctl->uplane_inactivity_timer = 0; - } + AssertFatal(alloc, + "could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n", + rnti, frame, slot); + sched_ctrl->rbStart = rbStart; + sched_ctrl->rbSize = rbSize; + sched_ctrl->time_domain_allocation = 2; + if (!UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table) + sched_ctrl->mcsTableIdx = 0; else { - - LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP); - - // fill dlsch_buffer with random data - for (i = 0; i < TBS_bytes; i++){ - mac_sdus[i] = (unsigned char) (lrand48()&0xff); - //((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff); - } - //Sending SDUs with size 1 - //Initialize elements of sdu_lcids and sdu_lengths - sdu_lcids[0] = 0x3f; // DRB - sdu_lengths[0] = TBS_bytes - ta_len - 3; - header_length_total += 2 + (sdu_lengths[0] >= 128); - sdu_length_total += sdu_lengths[0]; - num_sdus +=1; - - #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 *)gNB_mac->UE_info.DLSCH_pdu[CC_id][0][0].payload[0])[i]); - } - } - #endif - - } - - UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total; - - // there is at least one SDU or TA command - // if (num_sdus > 0 ){ - if (ta_len + sdu_length_total + header_length_total > 0) { - - // Check if there is data from RLC or CE - if (TBS_bytes >= 2 + header_length_total + sdu_length_total + ta_len) { - // we have to consider padding - // padding param currently not in use - //padding = TBS_bytes - header_length_total - sdu_length_total - ta_len - 1; - post_padding = 1; - } else { - //padding = 0; - post_padding = 0; - } - - offset = nr_generate_dlsch_pdu(module_idP, - &UE_info->UE_sched_ctrl[UE_id], - (unsigned char *) mac_sdus, - (unsigned char *) gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0], - num_sdus, //num_sdus - sdu_lengths, - sdu_lcids, - 255, // no drx - NULL, // contention res id - post_padding); - - // Padding: fill remainder of DLSCH with 0 - if (post_padding > 0){ - for (int j = 0; j < (TBS_bytes - offset); j++) - gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0; - } - - configure_fapi_dl_Tx(module_idP, frameP, slotP, dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]); - - if(IS_SOFTMODEM_NOS1){ - #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. ", mac_payload[i]); - } - #endif - } else { -#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, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]); - } - } -#endif - } - } - else { // There is no data from RLC or MAC header, so don't schedule + if (*UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table == 0) + sched_ctrl->mcsTableIdx = 1; + else + sched_ctrl->mcsTableIdx = 2; } + sched_ctrl->mcs = 9; + sched_ctrl->numDmrsCdmGrpsNoData = 1; + /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */ + sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head; + /* mark the corresponding RBs as used */ + for (int rb = 0; rb < sched_ctrl->rbSize; rb++) + vrb_map[rb + sched_ctrl->rbStart] = 1; } -int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) { +bool nr_ul_preprocessor_phytest(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + uint64_t ulsch_in_slot_bitmap) { + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + NR_COMMON_channels_t *cc = nr_mac->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + NR_UE_info_t *UE_info = &nr_mac->UE_info; - uint8_t hrq_id; - uint8_t max_ul_harq_pids = 3; // temp: for testing - // schedule active harq processes - NR_UE_ul_harq_t cur_harq; - for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) { - cur_harq = sched_ctrl->ul_harq_processes[hrq_id]; - if (cur_harq.state==ACTIVE_NOT_SCHED) { -#ifdef UL_HARQ_PRINT - printf("[SCHED] Found ulharq id %d, scheduling it for retransmission\n",hrq_id); -#endif - return hrq_id; - } - } + AssertFatal(UE_info->num_UEs <= 1, + "%s() cannot handle more than one UE, but found %d\n", + __func__, + UE_info->num_UEs); + if (UE_info->num_UEs == 0) + return false; - // schedule new harq processes - for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) { - cur_harq = sched_ctrl->ul_harq_processes[hrq_id]; - if (cur_harq.state==INACTIVE) { -#ifdef UL_HARQ_PRINT - printf("[SCHED] Found new ulharq id %d, scheduling it\n",hrq_id); -#endif - return hrq_id; - } - } - LOG_E(MAC,"All UL HARQ processes are busy. Cannot schedule ULSCH\n"); - return -1; -} + const int UE_id = 0; + const int CC_id = 0; -long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) { - DevAssert(ubwp); - const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - if (tda_list->k2) - return *tda_list->k2; - else if (mu < 2) - return 1; - else if (mu == 2) - return 2; - else - return 3; -} + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; -void schedule_fapi_ul_pdu(int Mod_idP, - frame_t frameP, - sub_frame_t slotP, - int num_slots_per_tdd, - int ul_slots, - int time_domain_assignment, - uint64_t ulsch_in_slot_bitmap) { - - 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 mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; - int UE_id = 0; - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id); - - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; - AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; - int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; - NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup; - - AssertFatal(time_domain_assignmentbwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count, - "time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count); - - int K2 = get_K2(ubwp, time_domain_assignment,mu); - /* check if slot is UL, and for phy test verify that it is in first TDD - * period, slot 8 (for K2=2, this is at slot 6 in the gNB; because of UE + const int tda = 1; + const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = + sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + AssertFatal(tda < tdaList->list.count, + "time domain assignment %d >= %d\n", + tda, + tdaList->list.count); + int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu); + const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); + const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; + /* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE * limitations). Note that if K2 or the TDD configuration is changed, below * conditions might exclude each other and never be true */ - const int slot_idx = (slotP + K2) % num_slots_per_tdd; - if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx) - && (!get_softmodem_params()->phy_test || slot_idx == 8)) { - nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; - UL_dci_req->SFN = frameP; - UL_dci_req->Slot = slotP; - nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu; + if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8)) + return false; - 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"); + const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + uint16_t rbStart = 0; + uint16_t rbSize = 50; /* due to OAI UE limitations */ + if (rbSize>bw) + rbSize = bw; - uint16_t rnti = UE_info->rnti[UE_id]; - - int first_ul_slot = num_slots_per_tdd - ul_slots; - NR_sched_pusch *pusch_sched = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot]; - pusch_sched->frame = frameP; - pusch_sched->slot = slotP + K2; - pusch_sched->active = true; - nfapi_nr_pusch_pdu_t *pusch_pdu = &pusch_sched->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]; - - int dci_formats[2]; - int rnti_types[2]; - - NR_SearchSpace_t *ss; - int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - - 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"); - - int found=0; - - 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->searchSpaceType->present == target_ss) { - found=1; - break; - } - } - AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) - dci_formats[0] = NR_UL_DCI_FORMAT_0_1; - else - dci_formats[0] = NR_UL_DCI_FORMAT_0_0; - - rnti_types[0] = NR_RNTI_C; - - //Resource Allocation in time domain - int startSymbolAndLength=0; - int StartSymbolIndex,NrOfSymbols,mapping_type; - - startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength; - SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols); - pusch_pdu->start_symbol_index = StartSymbolIndex; - pusch_pdu->nr_of_symbols = NrOfSymbols; - - mapping_type = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType; - - 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; - - if (pusch_Config->transformPrecoder == NULL) { - if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) - pusch_pdu->transform_precoding = 1; - else - pusch_pdu->transform_precoding = 0; - } - else - pusch_pdu->transform_precoding = *pusch_Config->transformPrecoder; - if (pusch_Config->dataScramblingIdentityPUSCH != NULL) - pusch_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH; - else - pusch_pdu->data_scrambling_id = *scc->physCellId; - - pusch_pdu->mcs_index = 9; - if (pusch_pdu->transform_precoding) - pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0, - dci_formats[0], rnti_types[0], target_ss, false); - else - pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1, - dci_formats[0], rnti_types[0], target_ss, false); - - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); - if (pusch_Config->tp_pi2BPSK!=NULL) { - if(((pusch_pdu->mcs_table==3)&&(pusch_pdu->mcs_index<2)) || - ((pusch_pdu->mcs_table==4)&&(pusch_pdu->mcs_index<6))) { - pusch_pdu->target_code_rate = pusch_pdu->target_code_rate>>1; - pusch_pdu->qam_mod_order = pusch_pdu->qam_mod_order<<1; - } - } - pusch_pdu->nrOfLayers = 1; - - //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] - if (pusch_Config->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) { - pusch_pdu->resource_alloc = 1; //type 1 - pusch_pdu->rb_start = 0; - if (get_softmodem_params()->phy_test==1) - pusch_pdu->rb_size = 50; - else - pusch_pdu->rb_size = pusch_pdu->bwp_size; - } - else - AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - - pusch_pdu->vrb_to_prb_mapping = 0; - - if (pusch_Config->frequencyHopping==NULL) - pusch_pdu->frequency_hopping = 0; - else - pusch_pdu->frequency_hopping = 1; - - //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] - //pusch_pdu->uplink_frequency_shift_7p5khz = 0; - - - // -------------------- - // ------- DMRS ------- - // -------------------- - NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; - if (mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA) - NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup; - else - NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; - if (NR_DMRS_UplinkConfig->dmrs_Type == NULL) - pusch_pdu->dmrs_config_type = 0; - else - pusch_pdu->dmrs_config_type = 1; - pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] - if (pusch_pdu->transform_precoding) { // transform precoding disabled - long *scramblingid; - if (pusch_pdu->scid == 0) - scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; - else - scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1; - if (scramblingid == NULL) - pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; - else - pusch_pdu->ul_dmrs_scrambling_id = *scramblingid; - } - else { - pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; - if (NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) - pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity; - else - pusch_pdu->pusch_identity = *scc->physCellId; - } - pusch_dmrs_AdditionalPosition_t additional_pos; - if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL) - additional_pos = 2; - else { - if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3) - additional_pos = 3; - else - additional_pos = *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition; - } - pusch_maxLength_t pusch_maxLength; - if (NR_DMRS_UplinkConfig->maxLength == NULL) - pusch_maxLength = 1; - else - pusch_maxLength = 2; - uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, mapping_type, additional_pos, pusch_maxLength); - pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index; - - pusch_pdu->num_dmrs_cdm_grps_no_data = 1; - pusch_pdu->dmrs_ports = 1; - // -------------------------------------------------------------------------------------------------------------------------------------------- - - // -------------------- - // ------- PTRS ------- - // -------------------- - if (NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) { - // TODO to be fixed from RRC config - uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig - uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig - uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig - uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig - uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig - pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table); - pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size); - pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); - pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - - pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS - } - else{ - pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS - } - - // -------------------------------------------------------------------------------------------------------------------------------------------- - - //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] - //Optional Data only included if indicated in pduBitmap - int8_t harq_id = select_ul_harq_pid(&UE_info->UE_sched_ctrl[UE_id]); - if (harq_id < 0) return; - NR_UE_ul_harq_t *cur_harq = &UE_info->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id]; - pusch_pdu->pusch_data.harq_process_id = harq_id; - pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi; - pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round]; - - cur_harq->state = ACTIVE_SCHED; - cur_harq->last_tx_slot = pusch_sched->slot; - - uint8_t num_dmrs_symb = 0; - - for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++) - num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1); - - uint8_t N_PRB_DMRS; - if (pusch_pdu->dmrs_config_type == 0) { - N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6; - } - else { - N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4; - } - - pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order, - pusch_pdu->target_code_rate, - pusch_pdu->rb_size, - pusch_pdu->nr_of_symbols, - N_PRB_DMRS * num_dmrs_symb, - 0, //nb_rb_oh - 0, - pusch_pdu->nrOfLayers)>>3; - - UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; - if (cur_harq->round == 0) UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size; - - pusch_pdu->pusch_data.num_cb = 0; //CBG not supported - //pusch_pdu->pusch_data.cb_present_and_position; - //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; - UL_dci_req->numPdus+=1; - - - LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); - - uint8_t nr_of_candidates, aggregation_level; - find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); - NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */); - int CCEIndex = allocate_nr_CCEs( - nr_mac, - bwp, - coreset, - aggregation_level, - UE_info->rnti[UE_id], - 0); // m - if (CCEIndex < 0) { - LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__); - pusch_sched->active = false; - return; - } - else { - nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_info->rnti[UE_id], - ss, - coreset, - scc, - bwp, - aggregation_level, - CCEIndex); - - dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t)); - config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_info->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id); - fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); - free(dci_pdu_rel15); + uint16_t *vrb_map_UL = + &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; + for (int i = rbStart; i < rbStart + rbSize; ++i) { + if (vrb_map_UL[i]) { + LOG_E(MAC, + "%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n", + __func__, + frame, + slot, + i); + return false; } } -} + sched_ctrl->sched_pusch.slot = sched_slot; + sched_ctrl->sched_pusch.frame = sched_frame; + + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + sched_ctrl->coreset = get_coreset( + sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + const int cid = sched_ctrl->coreset->controlResourceSetId; + const uint16_t Y = UE_info->Y[UE_id][cid][slot]; + const int m = UE_info->num_pdcch_cand[UE_id][cid]; + sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], + sched_ctrl->active_bwp, + sched_ctrl->coreset, + sched_ctrl->aggregation_level, + Y, + m, + nr_of_candidates); + if (sched_ctrl->cce_index < 0) { + LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__); + return false; + } + UE_info->num_pdcch_cand[UE_id][cid]++; + + sched_ctrl->sched_pusch.time_domain_allocation = tda; + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; + const uint8_t num_dmrs_cdm_grps_no_data = 1; + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) + nr_save_pusch_fields(scc, + sched_ctrl->active_ubwp, + dci_format, + tda, + num_dmrs_cdm_grps_no_data, + ps); + + const int mcs = 9; + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + sched_pusch->mcs = mcs; + sched_pusch->rbStart = rbStart; + sched_pusch->rbSize = rbSize; + /* get the PID of a HARQ process awaiting retransmission, or -1 for "any new" */ + sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head; + + /* Calculate TBS from MCS */ + sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); + if (ps->pusch_Config->tp_pi2BPSK + && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + sched_pusch->R >>= 1; + sched_pusch->Qm <<= 1; + } + sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, + sched_pusch->R, + sched_pusch->rbSize, + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->num_dmrs_symb, + 0, // nb_rb_oh + 0, + 1 /* NrOfLayers */) + >> 3; + + /* mark the corresponding RBs as used */ + for (int rb = rbStart; rb < rbStart + rbSize; rb++) + vrb_map_UL[rb] = 1; + return true; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index c0a0d47905..5abae7486b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -32,7 +32,6 @@ #include "assertions.h" -#include "LAYER2/MAC/mac.h" #include "NR_MAC_gNB/nr_mac_gNB.h" #include "NR_MAC_COMMON/nr_mac_extern.h" @@ -48,9 +47,6 @@ #include "RRC/NR/nr_rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -//#include "LAYER2/MAC/pre_processor.c" -#include "pdcp.h" - #include "intertask_interface.h" #include "T.h" @@ -172,14 +168,21 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, NR_BWP_Downlink_t *bwp, NR_ControlResourceSet_t *coreset, int aggregation, - uint16_t n_RNTI, - int m) { + uint16_t Y, + int m, + int nr_of_candidates) { // uncomment these when we allocate for common search space // NR_COMMON_channels_t *cc = nr_mac->common_channels; // NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int coreset_id = coreset->controlResourceSetId; - int *cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id]; + + int *cce_list; + if(bwp->bwp_Id == 0) { + cce_list = nr_mac->cce_list[1][0]; + } else { + cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id]; + } int n_rb=0; for (int i=0;i<6;i++) @@ -189,15 +192,16 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, n_rb*=6; uint16_t N_reg = n_rb * coreset->duration; - uint16_t n_CI=0; - const uint32_t A[3]={39827,39829,39839}; - /* if n_RNTI is zero, this results in zero, too! */ - uint16_t Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0 + uint16_t n_CI = 0; - uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE; + const uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE; + const uint16_t M_s_max = nr_of_candidates; - uint16_t M_s_max = (aggregation==4)?4:(aggregation==8)?2:1; - int first_cce = aggregation * (( Y + (m*N_cce)/(aggregation*M_s_max) + n_CI ) % CEILIDIV(N_cce,aggregation)); + //PDCCH candidate index m in CORESET exceeds the maximum number of PDCCH candidates + if(m >= nr_of_candidates) + return -1; + + int first_cce = aggregation * (( Y + CEILIDIV((m*N_cce),(aggregation*M_s_max)) + n_CI ) % CEILIDIV(N_cce,aggregation)); for (int i=0;idci_format = dci_format; + ps->time_domain_allocation = tda; + + const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = + ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, + &ps->startSymbolIndex, + &ps->nrOfSymbols); + + ps->pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup; + if (!ps->pusch_Config->transformPrecoder) + ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; + else + ps->transform_precoding = *ps->pusch_Config->transformPrecoder; + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + if (ps->transform_precoding) + ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_Table, + 0, + ps->dci_format, + NR_RNTI_C, + target_ss, + false); + else { + ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_TableTransformPrecoder, + 1, + ps->dci_format, + NR_RNTI_C, + target_ss, + false); + num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol + } + + ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + + /* DMRS calculations */ + ps->mapping_type = tdaList->list.array[tda]->mappingType; + ps->NR_DMRS_UplinkConfig = + ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA + ? ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup + : ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup; + ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1; + const pusch_dmrs_AdditionalPosition_t additional_pos = + ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL + ? 2 + : (*ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == + NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3 + ? 3 + : *ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition); + const pusch_maxLength_t pusch_maxLength = + ps->NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2; + const uint16_t l_prime_mask = get_l_prime(ps->nrOfSymbols, + ps->mapping_type, + additional_pos, + pusch_maxLength); + ps->ul_dmrs_symb_pos = l_prime_mask << ps->startSymbolIndex; + uint8_t num_dmrs_symb = 0; + for(int i = ps->startSymbolIndex; i < ps->startSymbolIndex + ps->nrOfSymbols; i++) + num_dmrs_symb += (ps->ul_dmrs_symb_pos >> i) & 1; + ps->num_dmrs_symb = num_dmrs_symb; + ps->N_PRB_DMRS = ps->dmrs_config_type == 0 + ? num_dmrs_cdm_grps_no_data * 6 + : num_dmrs_cdm_grps_no_data * 4; +} + 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, @@ -426,231 +502,70 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, } -void nr_fill_nfapi_dl_pdu(int Mod_idP, - int UE_id, - int bwp_id, - NR_SearchSpace_t *ss, - NR_ControlResourceSet_t *coreset, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - int nrOfLayers, - uint8_t mcs, - uint16_t rbSize, - uint16_t rbStart, - uint8_t numDmrsCdmGrpsNoData, - nfapi_nr_dmrs_type_e dmrsConfigType, - uint8_t table_idx, - uint16_t R, - uint8_t Qm, - uint32_t TBS, - int time_domain_assignment, - int StartSymbolIndex, - int NrOfSymbols, - uint8_t aggregation_level, - int CCEIndex, - int harq_pid, - int ndi, - int round) { - gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; - NR_COMMON_channels_t *cc = nr_mac->common_channels; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; - AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; - memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; - dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); - - nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; - memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); - dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; - dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - - - pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id]; - pdsch_pdu_rel15->pduIndex = nr_mac->pdu_index[0]++; - - // BWP - pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; - if (bwp->bwp_Common->genericParameters.cyclicPrefix) - pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix; - else - pdsch_pdu_rel15->CyclicPrefix = 0; - - pdsch_pdu_rel15->NrOfCodewords = 1; - pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0); - pdsch_pdu_rel15->qamModOrder[0] = 2; - pdsch_pdu_rel15->mcsIndex[0] = mcs; - pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[round]; - pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; - pdsch_pdu_rel15->nrOfLayers = nrOfLayers; - pdsch_pdu_rel15->transmissionScheme = 0; - pdsch_pdu_rel15->refPoint = 0; // Point A - pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType; - pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; - pdsch_pdu_rel15->SCID = 0; - pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData; - pdsch_pdu_rel15->dmrsPorts = 1; - pdsch_pdu_rel15->resourceAlloc = 1; - pdsch_pdu_rel15->rbStart = rbStart; - pdsch_pdu_rel15->rbSize = rbSize; - pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP - pdsch_pdu_rel15->targetCodeRate[0] = R; - pdsch_pdu_rel15->qamModOrder[0] = Qm; - pdsch_pdu_rel15->TBSize[0] = TBS; - pdsch_pdu_rel15->mcsTable[0] = table_idx; - pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; - pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; - - // k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0; - pdsch_pdu_rel15->dlDmrsSymbPos = - fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, - scc->dmrs_TypeA_Position, - pdsch_pdu_rel15->NrOfSymbols); - - dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; - memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET); - - // bwp indicator - int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; - if (n_dl_bwp < 4) - dci_pdu_rel15[0].bwp_indicator.val = bwp_id; - else - dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 - // frequency domain assignment - if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) - dci_pdu_rel15[0].frequency_domain_assignment.val = - PRBalloc_to_locationandbandwidth0( - pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->rbStart, - NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, - 275)); - else - AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); - // time domain assignment - dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV; - // mcs and rv - dci_pdu_rel15[0].mcs = mcs; - dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; - // harq pid and ndi - dci_pdu_rel15[0].harq_pid = harq_pid; - dci_pdu_rel15[0].ndi = ndi; - // DAI - dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3; - - // TPC for PUCCH - dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 - // PUCCH resource indicator - dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; - // PDSCH to HARQ TI - dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator; - // antenna ports - dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 - // dmrs sequence initialization - dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; - LOG_D(MAC, - "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), " - "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", - dci_pdu_rel15[0].frequency_domain_assignment.val, - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, 275), - dci_pdu_rel15[0].time_domain_assignment.val, - dci_pdu_rel15[0].vrb_to_prb_mapping.val, - dci_pdu_rel15[0].mcs, - dci_pdu_rel15[0].tb_scaling, - dci_pdu_rel15[0].ndi, - dci_pdu_rel15[0].rv); - - nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_info->rnti[UE_id], - ss, - coreset, - scc, - bwp, - aggregation_level, - CCEIndex); - - int dci_formats[2]; - int rnti_types[2]; - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) - dci_formats[0] = NR_DL_DCI_FORMAT_1_1; - else - dci_formats[0] = NR_DL_DCI_FORMAT_1_0; - - rnti_types[0] = NR_RNTI_C; - - fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); +void config_uldci(const NR_BWP_Uplink_t *ubwp, + const nfapi_nr_pusch_pdu_t *pusch_pdu, + dci_pdu_rel15_t *dci_pdu_rel15, + int dci_format, + int time_domain_assignment, + uint8_t tpc, + int n_ubwp, + int bwp_id) { + const int bw = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dci_pdu_rel15->frequency_domain_assignment.val = + PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw); + dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; + dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; + dci_pdu_rel15->mcs = pusch_pdu->mcs_index; + dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator; + dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index; + dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id; + dci_pdu_rel15->tpc = tpc; + AssertFatal(ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); + switch (dci_format) { + case NR_UL_DCI_FORMAT_0_0: + dci_pdu_rel15->format_indicator = 0; + break; + case NR_UL_DCI_FORMAT_0_1: + dci_pdu_rel15->dai[0].val = 0; //TODO + // bwp indicator as per table 7.3.1.1.2-1 in 38.212 + dci_pdu_rel15->bwp_indicator.val = n_ubwp < 4 ? bwp_id : bwp_id - 1; + // SRS resource indicator + if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) { + AssertFatal(*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook, + "Non Codebook configuration non supported\n"); + dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS + } + // Antenna Ports + dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank + // DMRS sequence initialization + dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid; + break; + default : + AssertFatal(0, "Valid UL formats are 0_0 and 0_1\n"); + } LOG_D(MAC, - "DCI params: rnti %x, rnti_type %d, dci_format %d\n", - pdcch_pdu_rel15->dci_pdu.RNTI[0], - rnti_types[0], - dci_formats[0]); - LOG_D(MAC, - "coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", - (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, - pdcch_pdu_rel15->StartSymbolIndex, - pdcch_pdu_rel15->DurationSymbols); - - // I don't know why the following is not needed, but in this case we don't - // need additional calculations: - //const uint16_t N_RE_prime = NR_NB_SC_PER_RB * N_sh_symb - N_PRB_DMRS - N_PRB_oh; - //LOG_D(MAC, - // "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", - // N_RE_prime, - // N_sh_symb, - // N_PRB_DMRS, - // N_PRB_oh); - //pdsch_pdu_rel15->nb_mod_symbols = N_RE_prime*pdsch_pdu_rel15->n_prb*pdsch_pdu_rel15->nb_codewords; - - LOG_D(MAC, - "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d " - "nb_layers %d nb_codewords %d mcs %d TBS: %d\n", - pdsch_pdu_rel15->rbStart, - pdsch_pdu_rel15->rbSize, - pdsch_pdu_rel15->StartSymbolIndex, - pdsch_pdu_rel15->NrOfSymbols, - pdsch_pdu_rel15->nrOfLayers, - pdsch_pdu_rel15->NrOfCodewords, - pdsch_pdu_rel15->mcsIndex[0], - TBS); - - dl_req->nPDUs += 2; + "%s() ULDCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", + __func__, + dci_pdu_rel15->frequency_domain_assignment.val, + dci_pdu_rel15->time_domain_assignment.val, + dci_pdu_rel15->frequency_hopping_flag.val, + dci_pdu_rel15->mcs, + dci_pdu_rel15->tpc, + dci_pdu_rel15->ndi, + dci_pdu_rel15->rv); } -void nr_configure_pdcch(gNB_MAC_INST *nr_mac, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, - uint16_t rnti, +void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Downlink_t *bwp, - uint8_t aggregation_level, - int CCEIndex) { + NR_BWP_Downlink_t *bwp) +{ if (bwp) { // This is not the InitialBWP - pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix; @@ -694,31 +609,14 @@ void nr_configure_pdcch(gNB_MAC_INST *nr_mac, pdcch_pdu->ShiftIndex = 0; } - pdcch_pdu->CoreSetType = 1; - + if(coreset->controlResourceSetId == 0) { + pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; + } else{ + pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; + } + //precoderGranularity pdcch_pdu->precoderGranularity = coreset->precoderGranularity; - - pdcch_pdu->dci_pdu.RNTI[pdcch_pdu->numDlDci]=rnti; - - if (coreset->pdcch_DMRS_ScramblingID != NULL && - ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { - pdcch_pdu->dci_pdu.ScramblingId[pdcch_pdu->numDlDci] = *coreset->pdcch_DMRS_ScramblingID; - pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=rnti; - } - else { - pdcch_pdu->dci_pdu.ScramblingId[pdcch_pdu->numDlDci] = *scc->physCellId; - pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=0; - } - - pdcch_pdu->dci_pdu.AggregationLevel[pdcch_pdu->numDlDci] = aggregation_level; - pdcch_pdu->dci_pdu.CceIndex[pdcch_pdu->numDlDci] = CCEIndex; - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats==NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) - pdcch_pdu->dci_pdu.beta_PDCCH_1_0[pdcch_pdu->numDlDci]=0; - - pdcch_pdu->dci_pdu.powerControlOffsetSS[pdcch_pdu->numDlDci]=1; - pdcch_pdu->numDlDci++; } else { // this is for InitialBWP AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n"); @@ -787,8 +685,8 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, else pucch_pdu->hopping_id = *scc->physCellId; - pucch_pdu->bwp_size = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - pucch_pdu->bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pucch_pdu->bwp_size = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pucch_pdu->bwp_start = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); pucch_pdu->subcarrier_spacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; pucch_pdu->cyclic_prefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix; @@ -814,7 +712,11 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, AssertFatal(1==0,"Couldn't fine pucch resource indicator %d in PUCCH resource set %d for %d UCI bits",pucch_resource,i,O_uci); } if (pucchresset->pucch_ResourceSetId == 1 && O_uci>2) { +#if (NR_RRC_VERSION >= MAKE_VERSION(16, 0, 0)) + N3 = pucchresset->maxPayloadSize!= NULL ? *pucchresset->maxPayloadSize : 1706; +#else N3 = pucchresset->maxPayloadMinus1!= NULL ? *pucchresset->maxPayloadMinus1 : 1706; +#endif if (N2O_uci) { if (pucch_resource < n_list) resource_id = pucchresset->resourceList.list.array[pucch_resource]; @@ -931,7 +833,7 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, } -void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, +void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format, int bwp_id) { @@ -1007,571 +909,506 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, } -void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *secondaryCellGroup, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, +void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *secondaryCellGroup, + nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int *dci_formats, - int *rnti_types, + int dci_format, + int rnti_type, int N_RB, int bwp_id) { + uint8_t fsize = 0, pos = 0; - uint8_t fsize=0, pos=0; + uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload; + int dci_size = nr_dci_size(scc, secondaryCellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id); + pdcch_dci_pdu->PayloadSizeBits = dci_size; + AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported"); - for (int d=0;dnumDlDci;d++) { + if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) + prepare_dci(secondaryCellGroup, dci_pdu_rel15, dci_format, bwp_id); - uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->dci_pdu.Payload[d]; - int dci_size = nr_dci_size(scc,secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],rnti_types[d],N_RB,bwp_id); - pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d] = dci_size; - AssertFatal(pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); - - if(dci_formats[d]==NR_DL_DCI_FORMAT_1_1 || dci_formats[d]==NR_UL_DCI_FORMAT_0_1) - prepare_dci(secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],bwp_id); - - /// 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 |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,N_RB,dci_size-pos,*dci_pdu); - // Time domain assignment - pos+=4; - *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val&0xf) << (dci_size-pos)); - LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,dci_size-pos,*dci_pdu); - // VRB to PRB mapping - - pos++; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&0x1)<<(dci_size-pos); - LOG_D(MAC,"vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping.val,dci_size-pos,*dci_pdu); - // MCS - pos+=5; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); + /// Payload generation + 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 |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos)); + LOG_D(MAC, + "frequency-domain assignment %d (%d bits) N_RB_BWP %d=> %d (0x%lx)\n", + dci_pdu_rel15->frequency_domain_assignment.val, + fsize, + N_RB, + dci_size - pos, + *dci_pdu); + // Time domain assignment + pos += 4; + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val & 0xf) << (dci_size - pos)); + LOG_D(MAC, + "time-domain assignment %d (3 bits)=> %d (0x%lx)\n", + dci_pdu_rel15->time_domain_assignment.val, + dci_size - pos, + *dci_pdu); + // VRB to PRB mapping + pos++; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & 0x1) << (dci_size - pos); + LOG_D(MAC, + "vrb to prb mapping %d (1 bits)=> %d (0x%lx)\n", + dci_pdu_rel15->vrb_to_prb_mapping.val, + dci_size - pos, + *dci_pdu); + // MCS + pos += 5; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos); #ifdef DEBUG_FILL_DCI - LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); + LOG_I(MAC, "mcs %d (5 bits)=> %d (0x%lx)\n", dci_pdu_rel15->mcs, dci_size - pos, *dci_pdu); #endif - // TB scaling - pos+=2; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling&0x3)<<(dci_size-pos); + // TB scaling + pos += 2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling & 0x3) << (dci_size - pos); #ifdef DEBUG_FILL_DCI - LOG_I(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); + LOG_I(MAC, "tb_scaling %d (2 bits)=> %d (0x%lx)\n", dci_pdu_rel15->tb_scaling, dci_size - pos, *dci_pdu); #endif - break; - - case NR_RNTI_C: - - // indicating a DL DCI format 1bit - pos++; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&1)<<(dci_size-pos); - 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); - - // 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.val&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,dci_size-pos,*dci_pdu); - - uint16_t is_ra = 1; - for (int i=0; ifrequency_domain_assignment.val>>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.val&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.val&0xf) << (dci_size-pos)); - LOG_D(MAC,"Time domain assignment %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_domain_assignment.val,4,dci_size-pos,*dci_pdu); - - // VRB to PRB mapping 1bit - pos++; - *dci_pdu |= (dci_pdu_rel15->vrb_to_prb_mapping.val&1)<<(dci_size-pos); - LOG_D(MAC,"VRB to PRB %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->vrb_to_prb_mapping.val,1,dci_size-pos,*dci_pdu); - - // MCS 5bit //bit over 32, so dci_pdu ++ - pos+=5; - *dci_pdu |= (dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); - LOG_D(MAC,"MCS %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,5,dci_size-pos,*dci_pdu); - - // New data indicator 1bit - pos++; - *dci_pdu |= (dci_pdu_rel15->ndi&1)<<(dci_size-pos); - LOG_D(MAC,"NDI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->ndi,1,dci_size-pos,*dci_pdu); - - // Redundancy version 2bit - pos+=2; - *dci_pdu |= (dci_pdu_rel15->rv&0x3)<<(dci_size-pos); - LOG_D(MAC,"RV %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->rv,2,dci_size-pos,*dci_pdu); - - // HARQ process number 4bit - pos+=4; - *dci_pdu |= ((dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos)); - LOG_D(MAC,"HARQ_PID %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->harq_pid,4,dci_size-pos,*dci_pdu); - - // Downlink assignment index 2bit - pos+=2; - *dci_pdu |= ((dci_pdu_rel15->dai[0].val&3)<<(dci_size-pos)); - LOG_D(MAC,"DAI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->dai[0].val,2,dci_size-pos,*dci_pdu); - - // TPC command for scheduled PUCCH 2bit - pos+=2; - *dci_pdu |= ((dci_pdu_rel15->tpc&3)<<(dci_size-pos)); - LOG_D(MAC,"TPC %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->tpc,2,dci_size-pos,*dci_pdu); - - // PUCCH resource indicator 3bit - pos+=3; - *dci_pdu |= ((dci_pdu_rel15->pucch_resource_indicator&0x7)<<(dci_size-pos)); - LOG_D(MAC,"PUCCH RI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pucch_resource_indicator,3,dci_size-pos,*dci_pdu); - - // PDSCH-to-HARQ_feedback timing indicator 3bit - pos+=3; - *dci_pdu |= ((dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val&0x7)<<(dci_size-pos)); - LOG_D(MAC,"PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n",dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val,3,dci_size-pos,*dci_pdu); - - } //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.val>>(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.val>>(3-i))&1)<<(dci_size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&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.val>>(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.val>>(3-i))&1)<<(dci_size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&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.val>>(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.val>>(3-i))&1)<<(dci_size-pos++); - // VRB to PRB mapping 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&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[0].val>>(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.val>>(2-i))&1)<<(dci_size-pos++); - - break; + 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); + 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); + // 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.val & ((1 << fsize) - 1)) << (dci_size - pos)); + LOG_D(MAC, + "Freq domain assignment %d (%d bits)=> %d (0x%lx)\n", + dci_pdu_rel15->frequency_domain_assignment.val, + fsize, + dci_size - pos, + *dci_pdu); + uint16_t is_ra = 1; + for (int i = 0; i < fsize; i++) { + if (!((dci_pdu_rel15->frequency_domain_assignment.val >> i) & 1)) { + is_ra = 0; + 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.val>>(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.val>>(3-i))&1)<<(dci_size-pos++); - // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val&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.val&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.val>>(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.val>>(3-i))&1)<<(dci_size-pos++); - // Frequency hopping flag – 1 bit - *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val&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.val&1)<<(dci_size-pos++); - */ - 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.val & 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)); + } else { + // Time domain assignment 4bit + pos += 4; + *dci_pdu |= ((dci_pdu_rel15->time_domain_assignment.val & 0xf) << (dci_size - pos)); + LOG_D(MAC, + "Time domain assignment %d (%d bits)=> %d (0x%lx)\n", + dci_pdu_rel15->time_domain_assignment.val, + 4, + dci_size - pos, + *dci_pdu); + // VRB to PRB mapping 1bit + pos++; + *dci_pdu |= (dci_pdu_rel15->vrb_to_prb_mapping.val & 1) << (dci_size - pos); + LOG_D(MAC, + "VRB to PRB %d (%d bits)=> %d (0x%lx)\n", + dci_pdu_rel15->vrb_to_prb_mapping.val, + 1, + dci_size - pos, + *dci_pdu); + // MCS 5bit //bit over 32, so dci_pdu ++ + pos += 5; + *dci_pdu |= (dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos); + LOG_D(MAC, "MCS %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->mcs, 5, dci_size - pos, *dci_pdu); + // New data indicator 1bit + pos++; + *dci_pdu |= (dci_pdu_rel15->ndi & 1) << (dci_size - pos); + LOG_D(MAC, "NDI %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->ndi, 1, dci_size - pos, *dci_pdu); + // Redundancy version 2bit + pos += 2; + *dci_pdu |= (dci_pdu_rel15->rv & 0x3) << (dci_size - pos); + LOG_D(MAC, "RV %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->rv, 2, dci_size - pos, *dci_pdu); + // HARQ process number 4bit + pos += 4; + *dci_pdu |= ((dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos)); + LOG_D(MAC, "HARQ_PID %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->harq_pid, 4, dci_size - pos, *dci_pdu); + // Downlink assignment index 2bit + pos += 2; + *dci_pdu |= ((dci_pdu_rel15->dai[0].val & 3) << (dci_size - pos)); + LOG_D(MAC, "DAI %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->dai[0].val, 2, dci_size - pos, *dci_pdu); + // TPC command for scheduled PUCCH 2bit + pos += 2; + *dci_pdu |= ((dci_pdu_rel15->tpc & 3) << (dci_size - pos)); + LOG_D(MAC, "TPC %d (%d bits)=> %d (0x%lx)\n", dci_pdu_rel15->tpc, 2, dci_size - pos, *dci_pdu); + // PUCCH resource indicator 3bit + pos += 3; + *dci_pdu |= ((dci_pdu_rel15->pucch_resource_indicator & 0x7) << (dci_size - pos)); + LOG_D(MAC, + "PUCCH RI %d (%d bits)=> %d (0x%lx)\n", + dci_pdu_rel15->pucch_resource_indicator, + 3, + dci_size - pos, + *dci_pdu); + // PDSCH-to-HARQ_feedback timing indicator 3bit + pos += 3; + *dci_pdu |= ((dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val & 0x7) << (dci_size - pos)); + LOG_D(MAC, + "PDSCH to HARQ TI %d (%d bits)=> %d (0x%lx)\n", + dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val, + 3, + dci_size - pos, + *dci_pdu); + } // end else break; - case NR_UL_DCI_FORMAT_0_1: - switch(rnti_types[d]) - { - case NR_RNTI_C: - // Indicating a DL DCI format 1bit - pos=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&0x1)<<(dci_size-pos); - - // Carrier indicator - pos+=dci_pdu_rel15->carrier_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->carrier_indicator.val&((1<carrier_indicator.nbits)-1))<<(dci_size-pos); - - // UL/SUL Indicator - pos+=dci_pdu_rel15->ul_sul_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ul_sul_indicator.val&((1<ul_sul_indicator.nbits)-1))<<(dci_size-pos); - - // BWP indicator - pos+=dci_pdu_rel15->bwp_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator.val&((1<bwp_indicator.nbits)-1))<<(dci_size-pos); - - // Frequency domain resource assignment - pos+=dci_pdu_rel15->frequency_domain_assignment.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val&((1<frequency_domain_assignment.nbits)-1)) << (dci_size-pos); - - // Time domain resource assignment - pos+=dci_pdu_rel15->time_domain_assignment.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val&((1<time_domain_assignment.nbits)-1)) << (dci_size-pos); - - // Frequency hopping - pos+=dci_pdu_rel15->frequency_hopping_flag.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val&((1<frequency_hopping_flag.nbits)-1)) << (dci_size-pos); - - // MCS 5bit - pos+=5; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); - - // New data indicator 1bit - pos+=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi&0x1)<<(dci_size-pos); - - // Redundancy version 2bit - pos+=2; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv&0x3)<<(dci_size-pos); - - // HARQ process number 4bit - pos+=4; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos); - - // 1st Downlink assignment index - pos+=dci_pdu_rel15->dai[0].nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[0].val&((1<dai[0].nbits)-1))<<(dci_size-pos); - - // 2nd Downlink assignment index - pos+=dci_pdu_rel15->dai[1].nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[1].val&((1<dai[1].nbits)-1))<<(dci_size-pos); - - // TPC command for scheduled PUSCH 2bit - pos+=2; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc&0x3)<<(dci_size-pos); - - // SRS resource indicator - pos+=dci_pdu_rel15->srs_resource_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_resource_indicator.val&((1<srs_resource_indicator.nbits)-1))<<(dci_size-pos); - - // Precoding info and n. of layers - pos+=dci_pdu_rel15->precoding_information.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->precoding_information.val&((1<precoding_information.nbits)-1))<<(dci_size-pos); - - // Antenna ports - pos+=dci_pdu_rel15->antenna_ports.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->antenna_ports.val&((1<antenna_ports.nbits)-1))<<(dci_size-pos); - - // SRS request - pos+=dci_pdu_rel15->srs_request.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_request.val&((1<srs_request.nbits)-1))<<(dci_size-pos); - - // CSI request - pos+=dci_pdu_rel15->csi_request.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->csi_request.val&((1<csi_request.nbits)-1))<<(dci_size-pos); - - // CBG transmission information - pos+=dci_pdu_rel15->cbgti.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgti.val&((1<cbgti.nbits)-1))<<(dci_size-pos); - - // PTRS DMRS association - pos+=dci_pdu_rel15->ptrs_dmrs_association.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ptrs_dmrs_association.val&((1<ptrs_dmrs_association.nbits)-1))<<(dci_size-pos); - - // Beta offset indicator - pos+=dci_pdu_rel15->beta_offset_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->beta_offset_indicator.val&((1<beta_offset_indicator.nbits)-1))<<(dci_size-pos); - - // DMRS sequence initialization - pos+=dci_pdu_rel15->dmrs_sequence_initialization.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val&((1<dmrs_sequence_initialization.nbits)-1))<<(dci_size-pos); - - // UL-SCH indicator - pos+=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ulsch_indicator&0x1)<<(dci_size-pos); - - 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; i < fsize; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val >> (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.val >> (3 - i)) & 1) << (dci_size - pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & 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_DL_DCI_FORMAT_1_1: - // Indicating a DL DCI format 1bit - pos=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator&0x1)<<(dci_size-pos); - - // Carrier indicator - pos+=dci_pdu_rel15->carrier_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->carrier_indicator.val&((1<carrier_indicator.nbits)-1))<<(dci_size-pos); - - // BWP indicator - pos+=dci_pdu_rel15->bwp_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator.val&((1<bwp_indicator.nbits)-1))<<(dci_size-pos); - - // Frequency domain resource assignment - pos+=dci_pdu_rel15->frequency_domain_assignment.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val&((1<frequency_domain_assignment.nbits)-1)) << (dci_size-pos); - - // Time domain resource assignment - pos+=dci_pdu_rel15->time_domain_assignment.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val&((1<time_domain_assignment.nbits)-1)) << (dci_size-pos); - - // VRB-to-PRB mapping - pos+=dci_pdu_rel15->vrb_to_prb_mapping.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val&((1<vrb_to_prb_mapping.nbits)-1))<<(dci_size-pos); - - // PRB bundling size indicator - pos+=dci_pdu_rel15->prb_bundling_size_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->prb_bundling_size_indicator.val&((1<prb_bundling_size_indicator.nbits)-1))<<(dci_size-pos); - - // Rate matching indicator - pos+=dci_pdu_rel15->rate_matching_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->rate_matching_indicator.val&((1<rate_matching_indicator.nbits)-1))<<(dci_size-pos); - - // ZP CSI-RS trigger - pos+=dci_pdu_rel15->zp_csi_rs_trigger.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->zp_csi_rs_trigger.val&((1<zp_csi_rs_trigger.nbits)-1)) << (dci_size-pos); - - //TB1 - // MCS 5bit - pos+=5; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); - - // New data indicator 1bit - pos+=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi&0x1)<<(dci_size-pos); - + case NR_RNTI_SI: + pos = 1; + // Freq domain assignment 0-16 bit + fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1)); + LOG_D(PHY, "fsize = %i\n", fsize); + for (int i = 0; i < fsize; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val >> (fsize - i - 1)) & 1) << (dci_size - pos++); + LOG_D(PHY, "dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val); + // Time domain assignment 4 bit + for (int i = 0; i < 4; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->time_domain_assignment.val >> (3 - i)) & 1) << (dci_size - pos++); + LOG_D(PHY, "dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & 1) << (dci_size - pos++); + LOG_D(PHY, "dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val); + // 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++); + LOG_D(PHY, "dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs); // Redundancy version 2bit - pos+=2; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv&0x3)<<(dci_size-pos); + for (int i = 0; i < 2; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->rv >> (1 - i)) & 1) << (dci_size - pos++); + LOG_D(PHY, "dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv); + // System information indicator 1bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->system_info_indicator&1)<<(dci_size-pos++); + LOG_D(PHY, "dci_pdu_rel15->system_info_indicator = %i\n", dci_pdu_rel15->system_info_indicator); + break; - //TB2 - // MCS 5bit - pos+=dci_pdu_rel15->mcs2.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs2.val&((1<mcs2.nbits)-1))<<(dci_size-pos); - + 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; i < fsize; i++) + *dci_pdu |= (((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val >> (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.val >> (3 - i)) & 1) << (dci_size - pos++); + // VRB to PRB mapping 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & 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 - pos+=dci_pdu_rel15->ndi2.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi2.val&((1<ndi2.nbits)-1))<<(dci_size-pos); - + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 1) << (dci_size - pos++); // Redundancy version 2bit - pos+=dci_pdu_rel15->rv2.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv2.val&((1<rv2.nbits)-1))<<(dci_size-pos); - + 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 - pos+=4; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid&0xf)<<(dci_size-pos); - - // Downlink assignment index - pos+=dci_pdu_rel15->dai[0].nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[0].val&((1<dai[0].nbits)-1))<<(dci_size-pos); - - // TPC command for scheduled PUCCH 2bit - pos+=2; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc&0x3)<<(dci_size-pos); - - // PUCCH resource indicator 3bit - pos+=3; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->pucch_resource_indicator&0x7)<<(dci_size-pos); - - // PDSCH-to-HARQ_feedback timing indicator - pos+=dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val&((1<pdsch_to_harq_feedback_timing_indicator.nbits)-1))<<(dci_size-pos); - - // Antenna ports - pos+=dci_pdu_rel15->antenna_ports.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->antenna_ports.val&((1<antenna_ports.nbits)-1))<<(dci_size-pos); - - // TCI - pos+=dci_pdu_rel15->transmission_configuration_indication.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->transmission_configuration_indication.val&((1<transmission_configuration_indication.nbits)-1))<<(dci_size-pos); - - // SRS request - pos+=dci_pdu_rel15->srs_request.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_request.val&((1<srs_request.nbits)-1))<<(dci_size-pos); - - // CBG transmission information - pos+=dci_pdu_rel15->cbgti.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgti.val&((1<cbgti.nbits)-1))<<(dci_size-pos); - - // CBG flushing out information - pos+=dci_pdu_rel15->cbgfi.nbits; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgfi.val&((1<cbgfi.nbits)-1))<<(dci_size-pos); - - // DMRS sequence init - pos+=1; - *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val&0x1)<<(dci_size-pos); + 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[0].val >> (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++); + // 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.val >> (2 - i)) & 1) << (dci_size - pos++); + break; } + break; + + case NR_UL_DCI_FORMAT_0_0: + switch (rnti_type) { + 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; i < fsize; i++) + *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val >> (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.val >> (3 - i)) & 1) << (dci_size - pos++); + // Frequency hopping flag – 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 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.val&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; i < fsize; i++) + *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val >> (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.val >> (3 - i)) & 1) << (dci_size - pos++); + // Frequency hopping flag – 1 bit + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & 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.val&1)<<(dci_size-pos++); + */ + break; + } + break; + + case NR_UL_DCI_FORMAT_0_1: + switch (rnti_type) { + case NR_RNTI_C: + // Indicating a DL DCI format 1bit + pos = 1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 0x1) << (dci_size - pos); + // Carrier indicator + pos += dci_pdu_rel15->carrier_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->carrier_indicator.val & ((1 << dci_pdu_rel15->carrier_indicator.nbits) - 1)) << (dci_size - pos); + // UL/SUL Indicator + pos += dci_pdu_rel15->ul_sul_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ul_sul_indicator.val & ((1 << dci_pdu_rel15->ul_sul_indicator.nbits) - 1)) << (dci_size - pos); + // BWP indicator + pos += dci_pdu_rel15->bwp_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator.val & ((1 << dci_pdu_rel15->bwp_indicator.nbits) - 1)) << (dci_size - pos); + // Frequency domain resource assignment + pos += dci_pdu_rel15->frequency_domain_assignment.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << dci_pdu_rel15->frequency_domain_assignment.nbits) - 1)) << (dci_size - pos); + // Time domain resource assignment + pos += dci_pdu_rel15->time_domain_assignment.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val & ((1 << dci_pdu_rel15->time_domain_assignment.nbits) - 1)) << (dci_size - pos); + // Frequency hopping + pos += dci_pdu_rel15->frequency_hopping_flag.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_hopping_flag.val & ((1 << dci_pdu_rel15->frequency_hopping_flag.nbits) - 1)) << (dci_size - pos); + // MCS 5bit + pos += 5; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos); + // New data indicator 1bit + pos += 1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 0x1) << (dci_size - pos); + // Redundancy version 2bit + pos += 2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv & 0x3) << (dci_size - pos); + // HARQ process number 4bit + pos += 4; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos); + // 1st Downlink assignment index + pos += dci_pdu_rel15->dai[0].nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[0].val & ((1 << dci_pdu_rel15->dai[0].nbits) - 1)) << (dci_size - pos); + // 2nd Downlink assignment index + pos += dci_pdu_rel15->dai[1].nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[1].val & ((1 << dci_pdu_rel15->dai[1].nbits) - 1)) << (dci_size - pos); + // TPC command for scheduled PUSCH 2bit + pos += 2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc & 0x3) << (dci_size - pos); + // SRS resource indicator + pos += dci_pdu_rel15->srs_resource_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_resource_indicator.val & ((1 << dci_pdu_rel15->srs_resource_indicator.nbits) - 1)) << (dci_size - pos); + // Precoding info and n. of layers + pos += dci_pdu_rel15->precoding_information.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->precoding_information.val & ((1 << dci_pdu_rel15->precoding_information.nbits) - 1)) << (dci_size - pos); + // Antenna ports + pos += dci_pdu_rel15->antenna_ports.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->antenna_ports.val & ((1 << dci_pdu_rel15->antenna_ports.nbits) - 1)) << (dci_size - pos); + // SRS request + pos += dci_pdu_rel15->srs_request.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_request.val & ((1 << dci_pdu_rel15->srs_request.nbits) - 1)) << (dci_size - pos); + // CSI request + pos += dci_pdu_rel15->csi_request.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->csi_request.val & ((1 << dci_pdu_rel15->csi_request.nbits) - 1)) << (dci_size - pos); + // CBG transmission information + pos += dci_pdu_rel15->cbgti.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgti.val & ((1 << dci_pdu_rel15->cbgti.nbits) - 1)) << (dci_size - pos); + // PTRS DMRS association + pos += dci_pdu_rel15->ptrs_dmrs_association.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ptrs_dmrs_association.val & ((1 << dci_pdu_rel15->ptrs_dmrs_association.nbits) - 1)) << (dci_size - pos); + // Beta offset indicator + pos += dci_pdu_rel15->beta_offset_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->beta_offset_indicator.val & ((1 << dci_pdu_rel15->beta_offset_indicator.nbits) - 1)) << (dci_size - pos); + // DMRS sequence initialization + pos += dci_pdu_rel15->dmrs_sequence_initialization.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val & ((1 << dci_pdu_rel15->dmrs_sequence_initialization.nbits) - 1)) << (dci_size - pos); + // UL-SCH indicator + pos += 1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ulsch_indicator & 0x1) << (dci_size - pos); + break; + } + break; + + case NR_DL_DCI_FORMAT_1_1: + // Indicating a DL DCI format 1bit + pos = 1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 0x1) << (dci_size - pos); + // Carrier indicator + pos += dci_pdu_rel15->carrier_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->carrier_indicator.val & ((1 << dci_pdu_rel15->carrier_indicator.nbits) - 1)) << (dci_size - pos); + // BWP indicator + pos += dci_pdu_rel15->bwp_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->bwp_indicator.val & ((1 << dci_pdu_rel15->bwp_indicator.nbits) - 1)) << (dci_size - pos); + // Frequency domain resource assignment + pos += dci_pdu_rel15->frequency_domain_assignment.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << dci_pdu_rel15->frequency_domain_assignment.nbits) - 1)) << (dci_size - pos); + // Time domain resource assignment + pos += dci_pdu_rel15->time_domain_assignment.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->time_domain_assignment.val & ((1 << dci_pdu_rel15->time_domain_assignment.nbits) - 1)) << (dci_size - pos); + // VRB-to-PRB mapping + pos += dci_pdu_rel15->vrb_to_prb_mapping.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->vrb_to_prb_mapping.val & ((1 << dci_pdu_rel15->vrb_to_prb_mapping.nbits) - 1)) << (dci_size - pos); + // PRB bundling size indicator + pos += dci_pdu_rel15->prb_bundling_size_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->prb_bundling_size_indicator.val & ((1 << dci_pdu_rel15->prb_bundling_size_indicator.nbits) - 1)) << (dci_size - pos); + // Rate matching indicator + pos += dci_pdu_rel15->rate_matching_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->rate_matching_indicator.val & ((1 << dci_pdu_rel15->rate_matching_indicator.nbits) - 1)) << (dci_size - pos); + // ZP CSI-RS trigger + pos += dci_pdu_rel15->zp_csi_rs_trigger.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->zp_csi_rs_trigger.val & ((1 << dci_pdu_rel15->zp_csi_rs_trigger.nbits) - 1)) << (dci_size - pos); + // TB1 + // MCS 5bit + pos += 5; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs & 0x1f) << (dci_size - pos); + // New data indicator 1bit + pos += 1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi & 0x1) << (dci_size - pos); + // Redundancy version 2bit + pos += 2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv & 0x3) << (dci_size - pos); + // TB2 + // MCS 5bit + pos += dci_pdu_rel15->mcs2.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs2.val & ((1 << dci_pdu_rel15->mcs2.nbits) - 1)) << (dci_size - pos); + // New data indicator 1bit + pos += dci_pdu_rel15->ndi2.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->ndi2.val & ((1 << dci_pdu_rel15->ndi2.nbits) - 1)) << (dci_size - pos); + // Redundancy version 2bit + pos += dci_pdu_rel15->rv2.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->rv2.val & ((1 << dci_pdu_rel15->rv2.nbits) - 1)) << (dci_size - pos); + // HARQ process number 4bit + pos += 4; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->harq_pid & 0xf) << (dci_size - pos); + // Downlink assignment index + pos += dci_pdu_rel15->dai[0].nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dai[0].val & ((1 << dci_pdu_rel15->dai[0].nbits) - 1)) << (dci_size - pos); + // TPC command for scheduled PUCCH 2bit + pos += 2; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc & 0x3) << (dci_size - pos); + // PUCCH resource indicator 3bit + pos += 3; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->pucch_resource_indicator & 0x7) << (dci_size - pos); + // PDSCH-to-HARQ_feedback timing indicator + pos += dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val & ((1 << dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.nbits) - 1)) << (dci_size - pos); + // Antenna ports + pos += dci_pdu_rel15->antenna_ports.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->antenna_ports.val & ((1 << dci_pdu_rel15->antenna_ports.nbits) - 1)) << (dci_size - pos); + // TCI + pos += dci_pdu_rel15->transmission_configuration_indication.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->transmission_configuration_indication.val & ((1 << dci_pdu_rel15->transmission_configuration_indication.nbits) - 1)) << (dci_size - pos); + // SRS request + pos += dci_pdu_rel15->srs_request.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->srs_request.val & ((1 << dci_pdu_rel15->srs_request.nbits) - 1)) << (dci_size - pos); + // CBG transmission information + pos += dci_pdu_rel15->cbgti.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgti.val & ((1 << dci_pdu_rel15->cbgti.nbits) - 1)) << (dci_size - pos); + // CBG flushing out information + pos += dci_pdu_rel15->cbgfi.nbits; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->cbgfi.val & ((1 << dci_pdu_rel15->cbgfi.nbits) - 1)) << (dci_size - pos); + // DMRS sequence init + pos += 1; + *dci_pdu |= ((uint64_t)dci_pdu_rel15->dmrs_sequence_initialization.val & 0x1) << (dci_size - pos); } + LOG_D(MAC, "DCI has %d bits and the payload is %lx\n", dci_size, *dci_pdu); } - - /* - 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)ssb_config.scs_common.value; @@ -1605,21 +1442,105 @@ int extract_length(int startSymbolAndLength) { /* * Dump the UL or DL UE_info into LOG_T(MAC) */ -void dump_nr_ue_list(NR_UE_list_t *listP) { +void dump_nr_list(NR_list_t *listP) +{ for (int j = listP->head; j >= 0; j = listP->next[j]) - LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]); + LOG_T(MAC, "NR list node %d => %d\n", j, listP->next[j]); } /* - * Add a UE to NR_UE_list listP + * Create a new NR_list */ -inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) { +void create_nr_list(NR_list_t *list, int len) +{ + list->head = -1; + list->next = calloc(len, sizeof(*list->next)); + AssertFatal(list, "cannot calloc() memory for NR_list_t->next\n"); + for (int i = 0; i < len; ++i) + list->next[i] = -1; + list->tail = -1; + list->len = len; +} + +/* + * Destroy an NR_list + */ +void destroy_nr_list(NR_list_t *list) +{ + free(list->next); +} + +/* + * Add an ID to an NR_list at the end, traversing the whole list. Note: + * add_tail_nr_list() is a faster alternative, but this implementation ensures + * we do not add an existing ID. + */ +void add_nr_list(NR_list_t *listP, int id) +{ int *cur = &listP->head; while (*cur >= 0) { - AssertFatal(*cur != UE_id, "UE_id %d already in NR_UE_list!\n", UE_id); + AssertFatal(*cur != id, "id %d already in NR_UE_list!\n", id); cur = &listP->next[*cur]; } - *cur = UE_id; + *cur = id; + if (listP->next[id] < 0) + listP->tail = id; +} + +/* + * Remove an ID from an NR_list + */ +void remove_nr_list(NR_list_t *listP, int id) +{ + int *cur = &listP->head; + int *prev = &listP->head; + while (*cur != -1 && *cur != id) { + prev = cur; + cur = &listP->next[*cur]; + } + AssertFatal(*cur != -1, "ID %d not found in UE_list\n", id); + int *next = &listP->next[*cur]; + *cur = listP->next[*cur]; + *next = -1; + listP->tail = *prev >= 0 && listP->next[*prev] >= 0 ? listP->tail : *prev; +} + +/* + * Add an ID to the tail of the NR_list in O(1). Note that there is + * corresponding remove_tail_nr_list(), as we cannot set the tail backwards and + * therefore need to go through the whole list (use remove_nr_list()) + */ +void add_tail_nr_list(NR_list_t *listP, int id) +{ + int *last = listP->tail < 0 ? &listP->head : &listP->next[listP->tail]; + *last = id; + listP->next[id] = -1; + listP->tail = id; +} + +/* + * Add an ID to the front of the NR_list in O(1) + */ +void add_front_nr_list(NR_list_t *listP, int id) +{ + const int ohead = listP->head; + listP->head = id; + listP->next[id] = ohead; + if (listP->tail < 0) + listP->tail = id; +} + +/* + * Remove an ID from the front of the NR_list in O(1) + */ +void remove_front_nr_list(NR_list_t *listP) +{ + AssertFatal(listP->head >= 0, "Nothing to remove\n"); + const int ohead = listP->head; + listP->head = listP->next[ohead]; + listP->next[ohead] = -1; + if (listP->head < 0) + listP->tail = -1; } int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) @@ -1639,19 +1560,68 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) return -1; } -int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ +void set_Y(int Y[3][160], rnti_t rnti) { + const int A[3] = {39827, 39829, 39839}; + const int D = 65537; + Y[0][0] = (A[0] * rnti) % D; + Y[1][0] = (A[1] * rnti) % D; + Y[2][0] = (A[2] * rnti) % D; + + for (int s = 1; s < 160; s++) { + Y[0][s] = (A[0] * Y[0][s - 1]) % D; + Y[1][s] = (A[1] * Y[1][s - 1]) % D; + Y[2][s] = (A[2] * Y[2][s - 1]) % D; + } +} + +int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) { +//------------------------------------------------------------------------------ + int RA_id; + RA_t *ra = (RA_t *) &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0]; + + for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) { + LOG_D(MAC, "Checking RA_id %d for %x : state %d\n", + RA_id, + rntiP, + ra[RA_id].state); + + if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP) + return RA_id; + } + + return -1; +} + +int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH n) +{ + switch (n) { + case NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n2: + return 2; + case NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n4: + return 4; + case NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n6: + return 6; + case NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n10: + return 10; + case NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n12: + return 12; + case NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16: + return 16; + default: + return 8; + } +} + +//------------------------------------------------------------------------------ +int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup) +{ NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info; - NR_COMMON_channels_t *cc = RC.nrmac[mod_idP]->common_channels; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int num_slots_ul = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) - num_slots_ul++; - LOG_W(MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n", + LOG_I(MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n", mod_idP, rntiP, UE_info->num_UEs); - dump_nr_ue_list(&UE_info->list); + dump_nr_list(&UE_info->list); for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { if (UE_info->active[i]) @@ -1661,40 +1631,65 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ UE_info->num_UEs++; UE_info->active[UE_id] = true; UE_info->rnti[UE_id] = rntiP; - add_nr_ue_list(&UE_info->list, UE_id); - memset((void *) &UE_info->UE_sched_ctrl[UE_id], - 0, - sizeof(NR_UE_sched_ctrl_t)); + UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup; + add_nr_list(&UE_info->list, UE_id); + memset(&UE_info->mac_stats[UE_id], 0, sizeof(NR_mac_stats_t)); + set_Y(UE_info->Y[UE_id], rntiP); + compute_csi_bitlen(secondaryCellGroup, UE_info, UE_id); + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + memset(sched_ctrl, 0, sizeof(*sched_ctrl)); + sched_ctrl->ta_frame = 0; + sched_ctrl->ta_update = 31; + sched_ctrl->ta_apply = false; + sched_ctrl->ul_rssi = 0; + /* set illegal time domain allocation to force recomputation of all fields */ + sched_ctrl->pusch_save.time_domain_allocation = -1; + const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated; - UE_info->UE_sched_ctrl[UE_id].ta_timer = 100; - UE_info->UE_sched_ctrl[UE_id].ta_update = 31; - UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0; - UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch **)malloc(num_slots_ul*sizeof(NR_sched_pucch *)); - for (int s=0; sUE_sched_ctrl[UE_id].sched_pucch[s] = (NR_sched_pucch *)malloc(2*sizeof(NR_sched_pucch)); - UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch)); + /* Set default BWPs */ + const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; + AssertFatal(bwpList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + bwpList->list.count); + const int bwp_id = 1; + sched_ctrl->active_bwp = bwpList->list.array[bwp_id - 1]; + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; + AssertFatal(ubwpList->list.count == 1, + "uplinkBWP_ToAddModList has %d BWP!\n", + ubwpList->list.count); + sched_ctrl->active_ubwp = ubwpList->list.array[bwp_id - 1]; - for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k][l], - 0, - sizeof(NR_sched_pucch)); + /* get Number of HARQ processes for this UE */ + AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup, + "no pdsch-ServingCellConfig found for UE %d\n", + UE_id); + const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig->pdsch_ServingCellConfig->choice.setup; + const int nrofHARQ = pdsch->nrofHARQ_ProcessesForPDSCH ? + get_nrofHARQ_ProcessesForPDSCH(*pdsch->nrofHARQ_ProcessesForPDSCH) : 8; + // add all available DL HARQ processes for this UE + create_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ); + for (int harq = 0; harq < nrofHARQ; harq++) + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq); + create_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ); + create_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ); - memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], - 0, - sizeof(NR_sched_pusch)); - } + // add all available UL HARQ processes for this UE + create_nr_list(&sched_ctrl->available_ul_harq, 16); + for (int harq = 0; harq < 16; harq++) + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); + create_nr_list(&sched_ctrl->feedback_ul_harq, 16); + create_nr_list(&sched_ctrl->retrans_ul_harq, 16); LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n", mod_idP, UE_id, rntiP); - dump_nr_ue_list(&UE_info->list); + dump_nr_list(&UE_info->list); return (UE_id); } // printf("MAC: cannot add new UE for rnti %x\n", rntiP); LOG_E(MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n"); - dump_nr_ue_list(&UE_info->list); + dump_nr_list(&UE_info->list); return -1; } @@ -1710,6 +1705,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { + if (UE_info->active[i] != TRUE) continue; if (UE_info->rnti[i] != rnti) @@ -1717,14 +1713,18 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) /* UE found, remove it */ UE_id = i; + UE_info->num_UEs--; UE_info->active[UE_id] = FALSE; UE_info->rnti[UE_id] = 0; - free(UE_info->UE_sched_ctrl[UE_id].sched_pucch); - free(UE_info->UE_sched_ctrl[UE_id].sched_pusch); - memset((void *) &UE_info->UE_sched_ctrl[UE_id], - 0, - sizeof(NR_UE_sched_ctrl_t)); + remove_nr_list(&UE_info->list, UE_id); + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + destroy_nr_list(&sched_ctrl->available_dl_harq); + destroy_nr_list(&sched_ctrl->feedback_dl_harq); + destroy_nr_list(&sched_ctrl->retrans_dl_harq); + destroy_nr_list(&sched_ctrl->available_ul_harq); + destroy_nr_list(&sched_ctrl->feedback_ul_harq); + destroy_nr_list(&sched_ctrl->retrans_ul_harq); LOG_I(MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n", mod_id, UE_id, @@ -1949,30 +1949,29 @@ void nr_csirs_scheduling(int Mod_idP, } -void find_aggregation_candidates(uint8_t *aggregation_level, - uint8_t *nr_of_candidates, - NR_SearchSpace_t *ss) { +bool find_free_CCE(module_id_t module_id, + sub_frame_t slot, + int UE_id){ + NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id]; + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + const int cid = sched_ctrl->coreset->controlResourceSetId; + const uint16_t Y = RC.nrmac[module_id]->UE_info.Y[UE_id][cid][slot]; + const int m = RC.nrmac[module_id]->UE_info.num_pdcch_cand[UE_id][cid]; + sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], + sched_ctrl->active_bwp, + sched_ctrl->coreset, + sched_ctrl->aggregation_level, + Y, + m, + nr_of_candidates); + if (sched_ctrl->cce_index < 0) + return false; - if (ss->nrofCandidates->aggregationLevel1 != NR_SearchSpace__nrofCandidates__aggregationLevel1_n0) { - *aggregation_level = 1; - *nr_of_candidates = ss->nrofCandidates->aggregationLevel1; - } - if (ss->nrofCandidates->aggregationLevel2 != NR_SearchSpace__nrofCandidates__aggregationLevel2_n0) { - *aggregation_level = 2; - *nr_of_candidates = ss->nrofCandidates->aggregationLevel2; - } - if (ss->nrofCandidates->aggregationLevel4 != NR_SearchSpace__nrofCandidates__aggregationLevel4_n0) { - *aggregation_level = 4; - *nr_of_candidates = ss->nrofCandidates->aggregationLevel4; - } - if (ss->nrofCandidates->aggregationLevel8 != NR_SearchSpace__nrofCandidates__aggregationLevel8_n0) { - *aggregation_level = 8; - *nr_of_candidates = ss->nrofCandidates->aggregationLevel8; - } - if (ss->nrofCandidates->aggregationLevel16 != NR_SearchSpace__nrofCandidates__aggregationLevel16_n0) { - *aggregation_level = 16; - *nr_of_candidates = ss->nrofCandidates->aggregationLevel16; - } + RC.nrmac[module_id]->UE_info.num_pdcch_cand[UE_id][cid]++; + return true; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index bf77310372..1165c8f0d5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -34,56 +34,73 @@ extern RAN_CONTEXT_t RC; + +void nr_fill_nfapi_pucch(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const NR_sched_pucch_t *pucch, + int UE_id) +{ + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + + nfapi_nr_ul_tti_request_t *future_ul_tti_req = + &RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot]; + AssertFatal(future_ul_tti_req->SFN == pucch->frame + && future_ul_tti_req->Slot == pucch->ul_slot, + "future UL_tti_req's frame.slot %d.%d does not match PUCCH %d.%d\n", + future_ul_tti_req->SFN, + future_ul_tti_req->Slot, + pucch->frame, + pucch->ul_slot); + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE; + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t); + nfapi_nr_pucch_pdu_t *pucch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pucch_pdu; + memset(pucch_pdu, 0, sizeof(nfapi_nr_pucch_pdu_t)); + future_ul_tti_req->n_pdus += 1; + + LOG_D(MAC, + "%4d.%2d Scheduling pucch reception in %4d.%2d: bits SR %d, ACK %d, CSI %d on res %d\n", + frame, + slot, + pucch->frame, + pucch->ul_slot, + pucch->sr_flag, + pucch->dai_c, + pucch->csi_bits, + pucch->resource_indicator); + + NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; + nr_configure_pucch(pucch_pdu, + scc, + UE_info->UE_sched_ctrl[UE_id].active_ubwp, + UE_info->rnti[UE_id], + pucch->resource_indicator, + pucch->csi_bits, + pucch->dai_c, + pucch->sr_flag); +} + void nr_schedule_pucch(int Mod_idP, - int UE_id, - int nr_ulmix_slots, frame_t frameP, sub_frame_t slotP) { - - uint16_t O_csi, O_ack, O_uci; - uint8_t O_sr = 0; // no SR in PUCCH implemented for now - NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id); + const NR_list_t *UE_list = &UE_info->list; - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; - int bwp_id=1; - NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; - nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const int n = sizeof(sched_ctrl->sched_pucch) / sizeof(*sched_ctrl->sched_pucch); + for (int i = 0; i < n; i++) { + NR_sched_pucch_t *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[i]; + const uint16_t O_ack = curr_pucch->dai_c; + const uint16_t O_csi = curr_pucch->csi_bits; + const uint8_t O_sr = curr_pucch->sr_flag; + if (O_ack + O_csi + O_sr == 0 + || frameP != curr_pucch->frame + || slotP != curr_pucch->ul_slot) + continue; - NR_sched_pucch *curr_pucch; - - for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k][l]; - O_ack = curr_pucch->dai_c; - O_csi = curr_pucch->csi_bits; - O_uci = O_ack + O_csi + O_sr; - if ((O_uci>0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) { - UL_tti_req->SFN = curr_pucch->frame; - UL_tti_req->Slot = curr_pucch->ul_slot; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE; - UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t); - nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu; - memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t)); - UL_tti_req->n_pdus+=1; - - LOG_D(MAC,"Scheduling pucch reception for frame %d slot %d with (%d, %d, %d) (SR ACK, CSI) bits\n", - frameP,slotP,O_sr,O_ack,curr_pucch->csi_bits); - - nr_configure_pucch(pucch_pdu, - scc, - ubwp, - UE_info->rnti[UE_id], - curr_pucch->resource_indicator, - O_csi, - O_ack, - O_sr); - - memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l], - 0, - sizeof(NR_sched_pucch)); - } + nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id); + memset(curr_pucch, 0, sizeof(*curr_pucch)); } } } @@ -111,7 +128,6 @@ void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type= csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.present; if (NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB ==UE_info->csi_report_template[UE_id][csi_report_id].CSI_Resource_type){ nzp_CSI_RS_SSB = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB; - UE_info->csi_report_template[UE_id][csi_report_id].nb_of_nzp_csi_report = nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.count:0; UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report = nzp_CSI_RS_SSB->csi_SSB_ResourceSetList!=NULL ? nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.count:0; } @@ -178,275 +194,441 @@ void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t } -uint16_t nr_get_csi_bitlen(int Mod_idP, - int UE_id, - uint8_t csi_report_id) { - - uint16_t csi_bitlen =0; - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - CRI_SSBRI_RSRP_bitlen_t * CSI_report_bitlen = NULL; - - CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0]); - csi_bitlen = ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + - CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * - (CSI_report_bitlen->nb_ssbri_cri -1 )) *UE_info->csi_report_template[UE_id][csi_report_id].nb_of_csi_ssb_report); - - return csi_bitlen; +uint16_t nr_get_csi_bitlen(const nr_csi_report_t *csi_report) +{ + const CRI_SSBRI_RSRP_bitlen_t *bitlen = &csi_report->CSI_report_bitlen[0]; + return bitlen->cri_ssbri_bitlen * bitlen->nb_ssbri_cri + + bitlen->rsrp_bitlen + + bitlen->diff_rsrp_bitlen * (bitlen->nb_ssbri_cri - 1) * csi_report->nb_of_csi_ssb_report; } void nr_csi_meas_reporting(int Mod_idP, - int UE_id, frame_t frame, - sub_frame_t slot, - int slots_per_tdd, - int ul_slots, - int n_slots_frame) { + sub_frame_t slot) +{ + NR_ServingCellConfigCommon_t *scc = + RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; + const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - NR_sched_pucch *curr_pucch; - NR_PUCCH_ResourceSet_t *pucchresset; - NR_CSI_ReportConfig_t *csirep; - NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; - NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; - NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[0]; - NR_PUCCH_Config_t *pucch_Config = ubwp->bwp_Dedicated->pucch_Config->choice.setup; + NR_list_t *UE_list = &UE_info->list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + const NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const NR_CSI_MeasConfig_t *csi_measconfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0, + "NO CSI report configuration available"); + NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count>0,"NO CSI report configuration available"); + for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; - for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + AssertFatal(csirep->reportConfigType.choice.periodic, + "Only periodic CSI reporting is implemented currently\n"); + int period, offset; + csi_period_offset(csirep, NULL, &period, &offset); + const int sched_slot = (period + offset) % n_slots_frame; + // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214 + // preparation is done in first slot of tdd period + if (frame % (period / n_slots_frame) != offset / n_slots_frame) + continue; + LOG_D(MAC, "CSI in frame %d slot %d\n", frame, sched_slot); - csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; + const NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; + const NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1 + const int n = pucchresset->resourceList.list.count; + int res_index = 0; + for (; res_index < n; res_index++) + if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource) + break; + AssertFatal(res_index < n, + "CSI resource not found among PUCCH resources\n"); - AssertFatal(csirep->reportConfigType.choice.periodic!=NULL,"Only periodic CSI reporting is implemented currently"); - int period, offset, sched_slot; - csi_period_offset(csirep,NULL,&period,&offset); - sched_slot = (period+offset)%n_slots_frame; - // prepare to schedule csi measurement reception according to 5.2.1.4 in 38.214 - // preparation is done in first slot of tdd period - if ( (frame%(period/n_slots_frame)==(offset/n_slots_frame)) && (slot==((sched_slot/slots_per_tdd)*slots_per_tdd))) { - - // we are scheduling pucch for csi in the first pucch occasion (this comes before ack/nack) - curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[sched_slot-slots_per_tdd+ul_slots][0]; - - NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0]; - - int found = -1; - pucchresset = pucch_Config->resourceSetToAddModList->list.array[1]; // set with formats >1 - int n_list = pucchresset->resourceList.list.count; - for (int i=0; iresourceList.list.array[i] == pucchcsires->pucch_Resource) - found = i; - } - AssertFatal(found>-1,"CSI resource not found among PUCCH resources"); - - curr_pucch->resource_indicator = found; - - n_list = pucch_Config->resourceToAddModList->list.count; - - // going through the list of PUCCH resources to find the one indexed by resource_id - for (int i=0; iresourceToAddModList->list.array[i]; - if (pucchres->pucch_ResourceId == *pucchresset->resourceList.list.array[found]) { - switch(pucchres->format.present){ - case NR_PUCCH_Resource__format_PR_format2: - if (pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL) - curr_pucch->simultaneous_harqcsi = false; - else - curr_pucch->simultaneous_harqcsi = true; - break; - case NR_PUCCH_Resource__format_PR_format3: - if (pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI == NULL) - curr_pucch->simultaneous_harqcsi = false; - else - curr_pucch->simultaneous_harqcsi = true; - break; - case NR_PUCCH_Resource__format_PR_format4: - if (pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI == NULL) - curr_pucch->simultaneous_harqcsi = false; - else - curr_pucch->simultaneous_harqcsi = true; - break; - default: - AssertFatal(1==0,"Invalid PUCCH format type"); - } - } - } - curr_pucch->csi_bits += nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id); // TODO function to compute CSI meas report bit size + // find free PUCCH that is in order with possibly existing PUCCH + // schedulings (other CSI, SR) + NR_sched_pucch_t *curr_pucch = &sched_ctrl->sched_pucch[2]; + AssertFatal(curr_pucch->csi_bits == 0 + && !curr_pucch->sr_flag + && curr_pucch->dai_c == 0, + "PUCCH not free at index 2 for UE %04x\n", + UE_info->rnti[UE_id]); curr_pucch->frame = frame; curr_pucch->ul_slot = sched_slot; + curr_pucch->resource_indicator = res_index; + curr_pucch->csi_bits += + nr_get_csi_bitlen(&UE_info->csi_report_template[UE_id][csi_report_id]); + + // going through the list of PUCCH resources to find the one indexed by resource_id + uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; + const int m = pucch_Config->resourceToAddModList->list.count; + for (int j = 0; j < m; j++) { + NR_PUCCH_Resource_t *pucchres = pucch_Config->resourceToAddModList->list.array[j]; + if (pucchres->pucch_ResourceId != *pucchresset->resourceList.list.array[res_index]) + continue; + int start = pucchres->startingPRB; + int len = 1; + uint64_t mask = 0; + switch(pucchres->format.present){ + case NR_PUCCH_Resource__format_PR_format2: + len = pucchres->format.choice.format2->nrofPRBs; + mask = ((1 << pucchres->format.choice.format2->nrofSymbols) - 1) << pucchres->format.choice.format2->startingSymbolIndex; + curr_pucch->simultaneous_harqcsi = pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI; + break; + case NR_PUCCH_Resource__format_PR_format3: + len = pucchres->format.choice.format3->nrofPRBs; + mask = ((1 << pucchres->format.choice.format3->nrofSymbols) - 1) << pucchres->format.choice.format3->startingSymbolIndex; + curr_pucch->simultaneous_harqcsi = pucch_Config->format3->choice.setup->simultaneousHARQ_ACK_CSI; + break; + case NR_PUCCH_Resource__format_PR_format4: + mask = ((1 << pucchres->format.choice.format4->nrofSymbols) - 1) << pucchres->format.choice.format4->startingSymbolIndex; + curr_pucch->simultaneous_harqcsi = pucch_Config->format4->choice.setup->simultaneousHARQ_ACK_CSI; + break; + default: + AssertFatal(0, "Invalid PUCCH format type\n"); + } + // verify resources are free + for (int i = start; i < start + len; ++i) { + vrb_map_UL[i] |= mask; + } + AssertFatal(!curr_pucch->simultaneous_harqcsi, + "UE %04x has simultaneous HARQ/CSI configured, but we don't support that\n", + UE_info->rnti[UE_id]); + } } } } +static void handle_dl_harq(module_id_t mod_id, + int UE_id, + int8_t harq_pid, + bool success) +{ + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[harq_pid]; + harq->feedback_slot = -1; + harq->is_waiting = false; + if (success) { + add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid); + harq->round = 0; + harq->ndi ^= 1; + } else if (harq->round == MAX_HARQ_ROUNDS) { + add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid); + harq->round = 0; + harq->ndi ^= 1; + NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; + stats->dlsch_errors++; + LOG_D(MAC, "retransmission error for UE %d (total %d)\n", UE_id, stats->dlsch_errors); + } else { + add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid); + harq->round++; + } +} -void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch, - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01, - nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234, - NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) { +void handle_nr_uci_pucch_0_1(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01) +{ + int UE_id = find_nr_UE_id(mod_id, uci_01->rnti); + if (UE_id < 0) { + LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti); + return; + } + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - // TODO - int max_harq_rounds = 4; // TODO define macro - - if (uci_01 != NULL) { - // handle harq - int harq_idx_s = 0; + // tpc (power control) + sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, + uci_01->ul_cqi, + 30); + NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; + const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + if (((uci_01->pduBitmap >> 1) & 0x01)) { // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { - // search for the right harq process - for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) { - // if the gNB received ack with a good confidence - if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { - if ((uci_01->harq->harq_list[harq_bit].harq_value == 1) && - (uci_01->harq->harq_confidence_level == 0)) { - // toggle NDI and reset round - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - else - sched_ctrl->harq_processes[harq_idx].round++; - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - harq_idx_s = harq_idx + 1; - // if the max harq rounds was reached - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - stats->dlsch_errors++; - } - break; - } - // if feedback slot processing is aborted - else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && - (sched_ctrl->harq_processes[harq_idx].is_waiting)) { - sched_ctrl->harq_processes[harq_idx].round++; - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - } + const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; + const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; + const int feedback_slot = (slot - 1 + num_slots) % num_slots; + /* In case of realtime problems: we can only identify a HARQ process by + * timing. If the HARQ process's feedback_slot is not the one we + * expected, we assume that processing has been aborted and we need to + * skip this HARQ process, which is what happens in the loop below. If + * you don't experience real-time problems, you might simply revert the + * commit that introduced these changes. */ + int8_t pid = sched_ctrl->feedback_dl_harq.head; + DevAssert(pid >= 0); + while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) { + LOG_W(MAC, + "expected feedback slot %d, but found %d instead\n", + sched_ctrl->harq_processes[pid].feedback_slot, + feedback_slot); + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + handle_dl_harq(mod_id, UE_id, pid, 0); + pid = sched_ctrl->feedback_dl_harq.head; + DevAssert(pid >= 0); } + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; + DevAssert(harq->is_waiting); + handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0); } } +} - if (uci_234 != NULL) { - int harq_idx_s = 0; - int acknack; +void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234) +{ + int UE_id = find_nr_UE_id(mod_id, uci_234->rnti); + if (UE_id < 0) { + LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti); + return; + } + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + // tpc (power control) + sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10, + uci_234->ul_cqi, + 30); + + NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; + const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + if ((uci_234->pduBitmap >> 1) & 0x01) { // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { - acknack = ((uci_234->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01; - for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) { - // if the gNB received ack with a good confidence or if the max harq rounds was reached - if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { - // TODO add some confidence level for when there is no CRC - if ((uci_234->harq.harq_crc != 1) && acknack) { - // toggle NDI and reset round - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - else - sched_ctrl->harq_processes[harq_idx].round++; - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - harq_idx_s = harq_idx + 1; - // if the max harq rounds was reached - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - stats->dlsch_errors++; - } - break; - } - // if feedback slot processing is aborted - else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && - (sched_ctrl->harq_processes[harq_idx].is_waiting)) { - sched_ctrl->harq_processes[harq_idx].round++; - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - } + const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01; + const int feedback_slot = (slot - 1 + num_slots) % num_slots; + /* In case of realtime problems: we can only identify a HARQ process by + * timing. If the HARQ process's feedback_slot is not the one we + * expected, we assume that processing has been aborted and we need to + * skip this HARQ process, which is what happens in the loop below. If + * you don't experience real-time problems, you might simply revert the + * commit that introduced these changes. */ + int8_t pid = sched_ctrl->feedback_dl_harq.head; + DevAssert(pid >= 0); + while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) { + LOG_W(MAC, + "expected feedback slot %d, but found %d instead\n", + sched_ctrl->harq_processes[pid].feedback_slot, + feedback_slot); + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + handle_dl_harq(mod_id, UE_id, pid, 0); + pid = sched_ctrl->feedback_dl_harq.head; + DevAssert(pid >= 0); } + remove_front_nr_list(&sched_ctrl->feedback_dl_harq); + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid]; + DevAssert(harq->is_waiting); + handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack); } } } // function to update pucch scheduling parameters in UE list when a USS DL is scheduled -void nr_acknack_scheduling(int Mod_idP, +bool nr_acknack_scheduling(int mod_id, int UE_id, - frame_t frameP, - sub_frame_t slotP, - int slots_per_tdd, - int *pucch_id, - int *pucch_occ) { + frame_t frame, + sub_frame_t slot) +{ + const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon; + const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; + const int nr_ulmix_slots = tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols != 0); + const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0; + const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots; + const int first_ul_slot_tdd = tdd->nrofDownlinkSlots + nr_slots_period * (slot / nr_slots_period); + const int CC_id = 0; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; - NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - NR_sched_pucch *curr_pucch; - int max_acknacks,pucch_res,first_ul_slot_tdd,k,i,l; - uint8_t pdsch_to_harq_feedback[8]; - int found = 0; - int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0) - nr_ulmix_slots++; + AssertFatal(slot < first_ul_slot_tdd + (tdd->nrofUplinkSymbols != 0), + "cannot handle multiple TDD periods (yet): slot %d first_ul_slot_tdd %d nrofUplinkSlots %ld\n", + slot, + first_ul_slot_tdd, + tdd->nrofUplinkSlots); - bool csi_pres=false; - for (k=0; kUE_sched_ctrl[UE_id].sched_pucch[k][0].csi_bits>0) - csi_pres=true; + /* for the moment, we consider: + * * only pucch_sched[0] holds HARQ (and SR) + * * we do not multiplex with CSI, which is always in pucch_sched[2] + * * SR uses format 0 and is allocated in the first UL (mixed) slot (and not + * later) + * * that the PUCCH resource set 0 (for up to 2 bits) points to the first N + * PUCCH resources, where N is the number of resources in the PUCCH + * resource set. This is used in pucch_index_used, which counts the used + * resources by index, and not by their ID! */ + NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id]; + NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; + AssertFatal(pucch->csi_bits == 0, + "%s(): csi_bits %d in sched_pucch[0]\n", + __func__, + pucch->csi_bits); + + const int max_acknacks = 2; + AssertFatal(pucch->dai_c + pucch->sr_flag <= max_acknacks, + "illegal number of bits in PUCCH of UE %d\n", + UE_id); + /* if the currently allocated PUCCH of this UE is full, allocate it */ + if (pucch->sr_flag + pucch->dai_c == max_acknacks) { + /* advance the UL slot information in PUCCH by one so we won't schedule in + * the same slot again */ + const int f = pucch->frame; + const int s = pucch->ul_slot; + nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id); + memset(pucch, 0, sizeof(*pucch)); + pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; + pucch->ul_slot = (s + 1) % n_slots_frame; + // we assume that only two indices over the array sched_pucch exist + const NR_sched_pucch_t *csi_pucch = &sched_ctrl->sched_pucch[2]; + // skip the CSI PUCCH if it is present and if in the next frame/slot + if (csi_pucch->csi_bits > 0 + && csi_pucch->frame == pucch->frame + && csi_pucch->ul_slot == pucch->ul_slot) { + AssertFatal(!csi_pucch->simultaneous_harqcsi, + "%s(): %d.%d cannot handle simultaneous_harqcsi, but found for UE %d\n", + __func__, + pucch->frame, + pucch->ul_slot, + UE_id); + nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id); + pucch->frame = s >= n_slots_frame - 2 ? (f + 1) % 1024 : f; + pucch->ul_slot = (s + 2) % n_slots_frame; + } } - // As a preference always schedule ack nacks in PUCCH0 (max 2 per slots) - // Unless there is CSI meas reporting scheduled in the period to avoid conflicts in the same slot - if (csi_pres) - max_acknacks=10; - else - max_acknacks=2; + /* if the UE's next PUCCH occasion is after the possible UL slots (within the + * same frame) or wrapped around to the next frame, then we assume there is + * no possible PUCCH allocation anymore */ + if ((pucch->frame == frame + && (pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots)) + || (pucch->frame == frame + 1)) + return false; // this is hardcoded for now as ue specific NR_SearchSpace__searchSpaceType_PR ss_type = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - get_pdsch_to_harq_feedback(Mod_idP,UE_id,ss_type,pdsch_to_harq_feedback); + uint8_t pdsch_to_harq_feedback[8]; + get_pdsch_to_harq_feedback(mod_id, UE_id, ss_type, pdsch_to_harq_feedback); - // for each possible ul or mixed slot - for (k=0; kUE_sched_ctrl[UE_id].sched_pucch[k][l]; - //if it is possible to schedule acknack in current pucch (no exclusive csi pucch) - if ((curr_pucch->csi_bits == 0) || (curr_pucch->simultaneous_harqcsi==true)) { - // if there is free room in current pucch structure - if (curr_pucch->dai_c-1){ - curr_pucch->resource_indicator = pucch_res; - curr_pucch->frame = frameP; - // first pucch occasion in first UL or MIXED slot - first_ul_slot_tdd = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; - i = 0; - while (i<8 && found == 0) { // look if timing indicator is among allowed values - if (pdsch_to_harq_feedback[i]==(first_ul_slot_tdd+k)-(slotP % slots_per_tdd)) - found = 1; - if (found == 0) i++; - } - if (found == 1) { - // computing slot in which pucch is scheduled - curr_pucch->dai_c++; - curr_pucch->ul_slot = first_ul_slot_tdd + k + (slotP - (slotP % slots_per_tdd)); - curr_pucch->timing_indicator = i; // index in the list of timing indicators - *pucch_id = k; - *pucch_occ = l; - return; - } - } - } - } + /* there is a scheduled SR or HARQ. Check whether we can use it for this + * ACKNACK */ + if (pucch->sr_flag + pucch->dai_c > 0) { + /* this UE already has a PUCCH occasion */ + DevAssert(pucch->frame == frame); + + // Find the right timing_indicator value. + int i = 0; + while (i < 8) { + if (pdsch_to_harq_feedback[i] == pucch->ul_slot - slot) + break; + ++i; + } + if (i >= 8) { + // we cannot reach this timing anymore, allocate and try again + const int f = pucch->frame; + const int s = pucch->ul_slot; + const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id); + memset(pucch, 0, sizeof(*pucch)); + pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; + pucch->ul_slot = (s + 1) % n_slots_frame; + return nr_acknack_scheduling(mod_id, UE_id, frame, slot); + } + + pucch->timing_indicator = i; + pucch->dai_c++; + // retain old resource indicator, and we are good + return true; + } + + /* we need to find a new PUCCH occasion */ + + NR_PUCCH_Config_t *pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; + DevAssert(pucch_Config->resourceToAddModList->list.count > 0); + DevAssert(pucch_Config->resourceSetToAddModList->list.count > 0); + const int n_res = pucch_Config->resourceSetToAddModList->list.array[0]->resourceList.list.count; + int *pucch_index_used = RC.nrmac[mod_id]->pucch_index_used[sched_ctrl->active_ubwp->bwp_Id]; + + /* if time information is outdated (e.g., last PUCCH occasion in last frame), + * set to first possible UL occasion in this frame. Note that if such UE is + * scheduled a lot and used all AckNacks, pucch->frame might have been + * wrapped around to next frame */ + if (frame != pucch->frame || pucch->ul_slot < first_ul_slot_tdd) { + DevAssert(pucch->sr_flag + pucch->dai_c == 0); + AssertFatal(frame + 1 != pucch->frame, + "frame wrap around not handled in %s() yet\n", + __func__); + pucch->frame = frame; + pucch->ul_slot = first_ul_slot_tdd; + } + + // increase to first slot in which PUCCH resources are available + while (pucch_index_used[pucch->ul_slot] >= n_res) { + pucch->ul_slot++; + /* if there is no free resource anymore, abort search */ + if ((pucch->frame == frame + && pucch->ul_slot >= first_ul_slot_tdd + nr_ulmix_slots) + || (pucch->frame == frame + 1)) { + LOG_E(MAC, + "%4d.%2d no free PUCCH resources anymore while searching for UE %d\n", + frame, + slot, + UE_id); + return false; } } - AssertFatal(1==0,"No Uplink slot available in accordance to allowed timing indicator\n"); -} + // advance ul_slot if it is not reachable by UE + pucch->ul_slot = max(pucch->ul_slot, slot + pdsch_to_harq_feedback[0]); + + // Find the right timing_indicator value. + int i = 0; + while (i < 8) { + if (pdsch_to_harq_feedback[i] == pucch->ul_slot - slot) + break; + ++i; + } + if (i >= 8) { + LOG_W(MAC, + "%4d.%2d could not find pdsch_to_harq_feedback for UE %d: earliest " + "ack slot %d\n", + frame, + slot, + UE_id, + pucch->ul_slot); + return false; + } + pucch->timing_indicator = i; // index in the list of timing indicators + + pucch->dai_c++; + const int pucch_res = pucch_index_used[pucch->ul_slot]; + pucch->resource_indicator = pucch_res; + pucch_index_used[pucch->ul_slot] += 1; + AssertFatal(pucch_index_used[pucch->ul_slot] <= n_res, + "UE %d in %4d.%2d: pucch_index_used is %d (%d available)\n", + UE_id, + pucch->frame, + pucch->ul_slot, + pucch_index_used[pucch->ul_slot], + n_res); + + /* verify that at that slot and symbol, resources are free. We only do this + * for initialCyclicShift 0 (we assume it always has that one), so other + * initialCyclicShifts can overlap with ICS 0!*/ + const NR_PUCCH_Resource_t *resource = + pucch_Config->resourceToAddModList->list.array[pucch_res]; + DevAssert(resource->format.present == NR_PUCCH_Resource__format_PR_format0); + if (resource->format.choice.format0->initialCyclicShift == 0) { + uint16_t *vrb_map_UL = &RC.nrmac[mod_id]->common_channels[CC_id].vrb_map_UL[pucch->ul_slot * MAX_BWP_SIZE]; + const uint16_t symb = 1 << resource->format.choice.format0->startingSymbolIndex; + AssertFatal((vrb_map_UL[resource->startingPRB] & symb) == 0, + "symbol %x is not free for PUCCH alloc in vrb_map_UL at RB %ld and slot %d\n", + symb, resource->startingPRB, pucch->ul_slot); + vrb_map_UL[resource->startingPRB] |= symb; + } + return true; +} void csi_period_offset(NR_CSI_ReportConfig_t *csirep, NR_NZP_CSI_RS_Resource_t *nzpcsi, @@ -566,24 +748,6 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep, } } - -int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l) { - - // to be updated later, for now simple implementation - // use the second allocation just in case there is csi in the first - // in that case use second resource (for a different symbol) see 9.2 in 38.213 - if (l==1) { - if (UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][0].csi_bits==0) - return -1; - else - return 1; - } - else - return 0; - -} - - uint16_t compute_pucch_prb_size(uint8_t format, uint8_t nr_prbs, uint16_t O_tot, @@ -658,5 +822,4 @@ uint16_t compute_pucch_prb_size(uint8_t format, else{ AssertFatal(1==0,"Not yet implemented"); } - } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 1fd121f351..90a1811b22 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -31,8 +31,35 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "executables/softmodem-common.h" -//#define ENABLE_MAC_PAYLOAD_DEBUG 1 +#include "common/utils/nr/nr_common.h" +//38.321 Table 6.1.3.1-1 +const uint32_t NR_SHORT_BSR_TABLE[32] = { + 0, 10, 14, 20, 28, 38, 53, 74, + 102, 142, 198, 276, 384, 535, 745, 1038, + 1446, 2014, 2806, 3909, 5446, 7587, 10570, 14726, +20516, 28581, 39818, 55474, 77284, 107669, 150000, 300000 +}; + +//38.321 Table 6.1.3.1-2 +const uint32_t NR_LONG_BSR_TABLE[256] ={ + 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 26, + 28, 30, 32, 34, 36, 38, 40, 43, 46, 49, 52, 55, 59, 62, 66, 71, + 75, 80, 85, 91, 97, 103, 110, 117, 124, 132, 141, 150, 160, 170, 181, 193, + 205, 218, 233, 248, 264, 281, 299, 318, 339, 361, 384, 409, 436, 464, 494, 526, + 560, 597, 635, 677, 720, 767, 817, 870, 926, 987, 1051, 1119, 1191, 1269, 1351, 1439, + 1532, 1631, 1737, 1850, 1970, 2098, 2234, 2379, 2533, 2698, 2873, 3059, 3258, 3469, 3694, 3934, + 4189, 4461, 4751, 5059, 5387, 5737, 6109, 6506, 6928, 7378, 7857, 8367, 8910, 9488, 10104, 10760, + 11458, 12202, 12994, 13838, 14736, 15692, 16711, 17795, 18951, 20181, 21491, 22885, 24371, 25953, 27638, 29431, + 31342, 33376, 35543, 37850, 40307, 42923, 45709, 48676, 51836, 55200, 58784, 62599, 66663, 70990, 75598, 80505, + 85730, 91295, 97221, 103532, 110252, 117409, 125030, 133146, 141789, 150992, 160793, 171231, 182345, 194182, 206786, 220209, + 234503, 249725, 265935, 283197, 301579, 321155, 342002, 364202, 387842, 413018, 439827, 468377, 498780, 531156, 565634, 602350, + 641449, 683087, 727427, 774645, 824928, 878475, 935498, 996222, 1060888, 1129752, 1203085, 1281179, 1364342, 1452903, 1547213, 1647644, + 1754595, 1868488, 1989774, 2118933, 2256475, 2402946, 2558924, 2725027, 2901912, 3090279, 3290873, 3504487, 3731968, 3974215, 4232186, 4506902, + 4799451, 5110989, 5442750, 5796046, 6172275, 6572925, 6999582, 7453933, 7937777, 8453028, 9001725, 9586039, 10208280, 10870913, 11576557, 12328006, +13128233, 13980403, 14887889, 15854280, 16883401, 17979324, 19146385, 20389201, 21712690, 23122088, 24622972, 26221280, 27923336, 29735875, 31666069, 33721553, +35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295 +}; void nr_process_mac_pdu( module_id_t module_idP, @@ -51,6 +78,13 @@ void nr_process_mac_pdu( uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; + NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; + int UE_id = find_nr_UE_id(module_idP, rnti); + if (UE_id == -1) { + LOG_E(MAC, "%s() UE_id == -1\n",__func__); + return; + } + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; // For both DL/UL-SCH // Except: // - UL/DL-SCH: fixed-size MAC CE(known by LCID) @@ -84,6 +118,9 @@ void nr_process_mac_pdu( LOG_D(MAC, "LCID received at gNB side: %d \n", rx_lcid); + unsigned char *ce_ptr; + int n_Lcg = 0; + switch(rx_lcid){ // MAC CE @@ -97,32 +134,25 @@ void nr_process_mac_pdu( case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION: // 38.321 Ch6.1.3.7 break; - case UL_SCH_LCID_S_BSR: - //38.321 section 6.1.3.1 - //fixed length - mac_ce_len =1; - /* Extract short BSR value */ - break; + case UL_SCH_LCID_S_BSR: case UL_SCH_LCID_S_TRUNCATED_BSR: //38.321 section 6.1.3.1 //fixed length mac_ce_len =1; - /* Extract short truncated BSR value */ + /* Extract short BSR value */ + ce_ptr = &pdu_ptr[mac_subheader_len]; + NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr; + sched_ctrl->estimated_ul_buffer = 0; + sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size]; + LOG_D(MAC, "SHORT BSR, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n", + bsr_s->LcgID, + bsr_s->Buffer_size, + NR_SHORT_BSR_TABLE[bsr_s->Buffer_size], + sched_ctrl->estimated_ul_buffer); break; case UL_SCH_LCID_L_BSR: - //38.321 section 6.1.3.1 - //variable length - mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; - mac_subheader_len = 2; - if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ - mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; - mac_subheader_len = 3; - } - /* Extract long BSR value */ - break; - case UL_SCH_LCID_L_TRUNCATED_BSR: //38.321 section 6.1.3.1 //variable length @@ -132,9 +162,27 @@ void nr_process_mac_pdu( mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8; mac_subheader_len = 3; } - /* Extract long truncated BSR value */ - break; + /* Extract long BSR value */ + ce_ptr = &pdu_ptr[mac_subheader_len]; + NR_BSR_LONG *bsr_l = (NR_BSR_LONG *) ce_ptr; + sched_ctrl->estimated_ul_buffer = 0; + n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 + + bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0; + + LOG_D(MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n", + bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4, + bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0); + + for (int n = 0; n < n_Lcg; n++){ + LOG_D(MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d", + n, n_Lcg, pdu_ptr[mac_subheader_len + 1 + n], + NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]); + sched_ctrl->estimated_ul_buffer += + NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]; + } + + break; case UL_SCH_LCID_C_RNTI: //38.321 section 6.1.3.2 @@ -214,88 +262,107 @@ void nr_process_mac_pdu( int UE_id = find_nr_UE_id(module_idP, rnti); RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n"); - for (i = 0; i < 32; i++) - LOG_T(MAC, "%x.", (pdu_ptr + mac_subheader_len)[i]); - - LOG_T(MAC, "\n"); #endif - if(IS_SOFTMODEM_NOS1){ - mac_rlc_data_ind(module_idP, - 0x1234, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), - mac_sdu_len, - 1, - NULL); - } - else{ - mac_rlc_data_ind(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), - mac_sdu_len, - 1, - NULL); - } + mac_rlc_data_ind(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + + /* Updated estimated buffer when receiving data */ + if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len) + sched_ctrl->estimated_ul_buffer -= mac_sdu_len; + else + sched_ctrl->estimated_ul_buffer = 0; break; default: - return; - break; + LOG_D(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); + return; + break; } pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); if (pdu_len < 0) { LOG_E(MAC, "%s() residual mac pdu length < 0!, pdu_len: %d\n", __func__, pdu_len); + LOG_E(MAC, "MAC PDU "); + for (int i = 0; i < 20; i++) // Only printf 1st - 20nd bytes + printf("%02x ", pdu_ptr[i]); + printf("\n"); return; } } } -void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu) { - - int max_harq_rounds = 4; // TODO define macro - uint8_t hrq_id = crc_pdu.harq_id; - NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id]; - if (cur_harq->state==ACTIVE_SCHED) { - if (!crc_pdu.tb_crc_status) { - cur_harq->ndi ^= 1; - cur_harq->round = 0; - cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant -#ifdef UL_HARQ_PRINT - printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id); -#endif - } else { - cur_harq->round++; - cur_harq->state = ACTIVE_NOT_SCHED; -#ifdef UL_HARQ_PRINT - printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id); -#endif - } - - if (!(cur_harq->roundndi ^= 1; - cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive - cur_harq->round = 0; - LOG_D(MAC,"[HARQ HANDLER] RNTI %x: Ulharq id %d crc failed in all round, freeing it for scheduler\n",crc_pdu.rnti,hrq_id); - stats->ulsch_errors++; - } +void handle_nr_ul_harq(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const nfapi_nr_crc_t *crc_pdu) +{ + int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti); + if (UE_id < 0) { + LOG_E(MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti); return; - } else - LOG_E(MAC,"Incorrect ULSCH HARQ process %d or invalid state %d\n",hrq_id,cur_harq->state); + } + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + int8_t harq_pid = sched_ctrl->feedback_ul_harq.head; + while (crc_pdu->harq_id != harq_pid || harq_pid < 0) { + LOG_W(MAC, + "Unexpected ULSCH HARQ PID %d (have %d) for RNTI %04x (ignore this warning for RA)\n", + crc_pdu->harq_id, + harq_pid, + crc_pdu->rnti); + if (harq_pid < 0) + return; + + remove_front_nr_list(&sched_ctrl->feedback_ul_harq); + sched_ctrl->ul_harq_processes[harq_pid].round++; + add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); + harq_pid = sched_ctrl->feedback_ul_harq.head; + } + remove_front_nr_list(&sched_ctrl->feedback_ul_harq); + NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; + DevAssert(harq->is_waiting); + harq->feedback_slot = -1; + harq->is_waiting = false; + if (!crc_pdu->tb_crc_status) { + harq->ndi ^= 1; + harq->round = 0; + LOG_D(MAC, + "Ulharq id %d crc passed for RNTI %04x\n", + harq_pid, + crc_pdu->rnti); + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); + } else if (harq->round == MAX_HARQ_ROUNDS) { + harq->ndi ^= 1; + harq->round = 0; + LOG_D(MAC, + "RNTI %04x: Ulharq id %d crc failed in all rounds\n", + crc_pdu->rnti, + harq_pid); + UE_info->mac_stats[UE_id].ulsch_errors++; + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); + } else { + harq->round++; + LOG_D(MAC, + "Ulharq id %d crc failed for RNTI %04x\n", + harq_pid, + crc_pdu->rnti); + add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid); + } } /* @@ -311,19 +378,21 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint16_t timing_advance, const uint8_t ul_cqi, const uint16_t rssi){ - int current_rnti = 0, UE_id = -1, harq_pid = 0; - gNB_MAC_INST *gNB_mac = NULL; - NR_UE_info_t *UE_info = NULL; - NR_UE_sched_ctrl_t *UE_scheduling_control = NULL; + gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP]; + NR_UE_info_t *UE_info = &gNB_mac->UE_info; - current_rnti = rntiP; - UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti); - gNB_mac = RC.nrmac[gnb_mod_idP]; - UE_info = &gNB_mac->UE_info; - int target_snrx10 = gNB_mac->pusch_target_snrx10; + const int current_rnti = rntiP; + const int UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti); + const int target_snrx10 = gNB_mac->pusch_target_snrx10; if (UE_id != -1) { - UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); + NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id]; + const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head; + + if (sduP) + T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), + T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(harq_pid), + T_BUFFER(sduP, sdu_lenP)); UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", @@ -349,6 +418,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n"); for (int i = 0; i < sdu_lenP ; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); @@ -356,55 +426,708 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, printf("%02x ",(unsigned char)sduP[i]); } printf("\n"); + #endif if (sduP != NULL){ LOG_D(MAC, "Received PDU at MAC gNB \n"); + + UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + if (UE_scheduling_control->sched_ul_bytes < 0) + UE_scheduling_control->sched_ul_bytes = 0; + nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); } else { + NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid]; + /* reduce sched_ul_bytes when cur_harq->round == 3 */ + if (cur_harq->round == 3){ + UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes; + if (UE_scheduling_control->sched_ul_bytes < 0) + UE_scheduling_control->sched_ul_bytes = 0; + } + } + } else { + if (!sduP) // check that CRC passed + return; - } - } - else if (sduP != NULL) { // if the CRC passed - // random access pusch with TC-RNTI - NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0]; - if (ra->state != WAIT_Msg3) { - LOG_E(MAC, - "expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n", - WAIT_Msg3, - ra->state, + T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP), + T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */, + T_BUFFER(sduP, sdu_lenP)); + + /* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3) + * and check the corresponding UE's RNTI match, in which case we activate + * it. */ + for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) { + NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i]; + if (ra->state != WAIT_Msg3) + continue; + + // random access pusch with TC-RNTI + if (ra->rnti != current_rnti) { + LOG_W(MAC, + "expected TC-RNTI %04x to match current RNTI %04x\n", + ra->rnti, + current_rnti); + continue; + } + const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup); + UE_info->UE_beam_index[UE_id] = ra->beam_id; + LOG_I(MAC, + "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " + "adding UE MAC Context UE_id %d/RNTI %04x\n", + gnb_mod_idP, + current_rnti, + UE_id, ra->rnti); - return; - } - if (ra->rnti != current_rnti) { - LOG_E(MAC, - "expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n", + // re-initialize ta update variables afrer RA procedure completion + UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP; + + free(ra->preambles.preamble_list); + ra->state = RA_IDLE; + LOG_I(MAC, + "reset RA state information for RA-RNTI %04x/index %d\n", ra->rnti, - ra->crnti, - current_rnti); + i); + return; } - free(ra->preambles.preamble_list); - ra->state = RA_IDLE; - LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti); - const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti); - UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup; - compute_csi_bitlen (ra->secondaryCellGroup, UE_info, UE_id); - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = - ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; - AssertFatal(bwpList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", - bwpList->list.count); - const int bwp_id = 1; - UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1]; - LOG_W(MAC, - "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, " - "adding UE MAC Context UE_id %d/RNTI %04x\n", - gnb_mod_idP, - current_rnti, - UE_id, - ra->crnti); } } +long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) { + DevAssert(ubwp); + const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; + if (tda_list->k2) + return *tda_list->k2; + else if (mu < 2) + return 1; + else if (mu == 2) + return 2; + else + return 3; +} + +int next_list_entry_looped(NR_list_t *list, int UE_id) +{ + if (UE_id < 0) + return list->head; + return list->next[UE_id] < 0 ? list->head : list->next[UE_id]; +} + +float ul_thr_ue[MAX_MOBILES_PER_GNB]; +int bsr0ue = -1; +void pf_ul(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + NR_list_t *UE_list, + int n_rb_sched, + uint8_t *rballoc_mask, + int max_num_ue) { + + const int CC_id = 0; + const int tda = 1; + NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + const int min_rb = 5; + float coeff_ue[MAX_MOBILES_PER_GNB]; + // UEs that could be scheduled + int ue_array[MAX_MOBILES_PER_GNB]; + NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB }; + + /* Hack: currently, we do not have SR, and need to schedule UEs continuously. + * To keep the wasted resources low, we switch UEs to be scheduled in a + * round-robin fashion below, and only schedule a UE with BSR=0 if it is the + * selected one */ + bsr0ue = next_list_entry_looped(UE_list, bsr0ue); + + /* Loop UE_list to calculate throughput and coeff */ + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + /* Calculate throughput */ + const float a = 0.0005f; // corresponds to 200ms window + const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes; + ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b; + + /* Save PUSCH field */ + /* we want to avoid a lengthy deduction of DMRS and other parameters in + * every TTI if we can save it, so check whether dci_format, TDA, or + * num_dmrs_cdm_grps_no_data has changed and only then recompute */ + sched_ctrl->sched_pusch.time_domain_allocation = tda; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific); + sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; + const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; + const uint8_t num_dmrs_cdm_grps_no_data = 1; + NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save; + if (ps->time_domain_allocation != tda + || ps->dci_format != dci_format + || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) + nr_save_pusch_fields(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); + + /* Check if retransmission is necessary */ + sched_ctrl->sched_pusch.ul_harq_pid = sched_ctrl->retrans_ul_harq.head; + if (sched_ctrl->sched_pusch.ul_harq_pid >= 0) { + /* RETRANSMISSION: Allocate retransmission*/ + /* Find free CCE */ + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE) { + LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); + continue; + } + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ + max_num_ue--; + if (max_num_ue < 0) + return; + + /* Save shced_frame and sched_slot before overwrite by previous PUSCH filed */ + NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[sched_ctrl->sched_pusch.ul_harq_pid]; + cur_harq->sched_pusch.frame = sched_ctrl->sched_pusch.frame; + cur_harq->sched_pusch.slot = sched_ctrl->sched_pusch.slot; + /* Get previous PSUCH filed info */ + sched_ctrl->sched_pusch = cur_harq->sched_pusch; + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + LOG_D(MAC, "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n", + frame, slot, UE_id, UE_info->rnti[UE_id], + sched_pusch->frame, sched_pusch->slot, + sched_pusch->rbSize); + + while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; + if (rbStart + sched_pusch->rbSize >= bwpSize) { + LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n", + UE_id, UE_info->rnti[UE_id]); + return; + } + sched_pusch->rbStart = rbStart; + /* no need to recompute the TBS, it will be the same */ + + /* Mark the corresponding RBs as used */ + n_rb_sched -= sched_pusch->rbSize; + for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0; + + continue; + } + + /* Calculate TBS from MCS */ + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + const int mcs = 9; + sched_pusch->mcs = mcs; + sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); + if (ps->pusch_Config->tp_pi2BPSK + && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + sched_pusch->R >>= 1; + sched_pusch->Qm <<= 1; + } + + /* Check BSR and schedule UE if it is zero to avoid starvation, since we do + * not have SR (yet) */ + if (sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes <= 0) { + if (UE_id != bsr0ue) + continue; + /* if no data, pre-allocate 5RB */ + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE) { + LOG_D(MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE_info->rnti[UE_id]); + continue; + } + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ + max_num_ue--; + if (max_num_ue < 0) + return; + + while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; + if (rbStart + min_rb >= bwpSize) { + LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n", + UE_id, UE_info->rnti[UE_id]); + return; + } + sched_pusch->rbStart = rbStart; + sched_pusch->rbSize = min_rb; + sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, + sched_pusch->R, + sched_pusch->rbSize, + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->num_dmrs_symb, + 0, // nb_rb_oh + 0, + 1 /* NrOfLayers */) + >> 3; + + /* Mark the corresponding RBs as used */ + n_rb_sched -= sched_pusch->rbSize; + for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0; + + continue; + } + + /* Create UE_sched for UEs eligibale for new data transmission*/ + add_tail_nr_list(&UE_sched, UE_id); + + /* Calculate coefficient*/ + const uint32_t tbs = nr_compute_tbs(sched_pusch->Qm, + sched_pusch->R, + 1, // rbSize + ps->nrOfSymbols, + ps->N_PRB_DMRS * ps->num_dmrs_symb, + 0, // nb_rb_oh + 0, + 1 /* NrOfLayers */) + >> 3; + coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id]; + LOG_D(MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", + b, UE_id, ul_thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]); + } + + + /* Loop UE_sched to find max coeff and allocate transmission */ + while (UE_sched.head >= 0 && max_num_ue> 0 && n_rb_sched > 0) { + /* Find max coeff */ + int *max = &UE_sched.head; /* Find max coeff: assume head is max */ + int *p = &UE_sched.next[*max]; + while (*p >= 0) { + /* Find max coeff: if the current one has larger coeff, save for later */ + if (coeff_ue[*p] > coeff_ue[*max]) + max = p; + p = &UE_sched.next[*p]; + } + /* Find max coeff: remove the max one: do not use remove_nr_list() since it + * goes through the whole list every time. Note that UE_sched.tail might + * not be set correctly anymore */ + const int UE_id = *max; + p = &UE_sched.next[*max]; + *max = UE_sched.next[*max]; + *p = -1; + + bool freeCCE = find_free_CCE(module_id, slot, UE_id); + if (!freeCCE) { + LOG_D(MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); + continue; + } + + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ + max_num_ue--; + if (max_num_ue < 0) + return; + + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + + + while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; + sched_pusch->rbStart = rbStart; + if (rbStart + min_rb >= bwpSize) { + LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n", + UE_id, UE_info->rnti[UE_id]); + return; + } + + /* Calculate the current scheduling bytes */ + const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0); + uint16_t rbSize = min_rb - 1; + do { + rbSize++; + sched_pusch->rbSize = rbSize; + sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, + sched_pusch->R, + sched_pusch->rbSize, + sched_ctrl->pusch_save.nrOfSymbols, + sched_ctrl->pusch_save.N_PRB_DMRS * sched_ctrl->pusch_save.num_dmrs_symb, + 0, // nb_rb_oh + 0, + 1 /* NrOfLayers */) + >> 3; + } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart+rbSize] && + sched_pusch->tb_size < B); + LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n", + rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B); + + /* Mark the corresponding RBs as used */ + n_rb_sched -= sched_pusch->rbSize; + for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) + rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0; + } +} + +bool nr_simple_ulsch_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + uint64_t ulsch_in_slot_bitmap) { + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + NR_COMMON_channels_t *cc = nr_mac->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + NR_UE_info_t *UE_info = &nr_mac->UE_info; + + if (UE_info->num_UEs == 0) + return false; + + const int CC_id = 0; + + /* NOT support different K2 in here, Get the K2 for first UE */ + int UE_id = UE_info->list.head; + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const int tda = 1; + const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = + sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + AssertFatal(tda < tdaList->list.count, + "time domain assignment %d >= %d\n", + tda, + tdaList->list.count); + + int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu); + const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); + const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; + if (!is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot)) + return false; + + sched_ctrl->sched_pusch.slot = sched_slot; + sched_ctrl->sched_pusch.frame = sched_frame; + + /* Confirm all the UE have same K2 as the first UE */ + for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + AssertFatal(K2 == get_K2(sched_ctrl->active_ubwp, tda, mu), + "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(sched_ctrl->active_ubwp, tda, mu), UE_id); + sched_ctrl->sched_pusch.slot = sched_slot; + sched_ctrl->sched_pusch.frame = sched_frame; + } + + /* Change vrb_map_UL to rballoc_mask */ + uint16_t *vrb_map_UL = + &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int st = 0, e = 0, len = 0; + for (int i = 0; i < bwpSize; i++) { + while (vrb_map_UL[i] == 1) + i++; + st = i; + while (vrb_map_UL[i] == 0) + i++; + if (i - st > len) { + len = i - st; + e = i - 1; + } + } + st = e - len + 1; + + uint8_t rballoc_mask[bwpSize]; + + /* Calculate mask: if any RB in vrb_map_UL is blocked (1), the current RB will be 0 */ + for (int i = 0; i < bwpSize; i++) + rballoc_mask[i] = i >= st && i <= e; + + /* proportional fair scheduling algorithm */ + pf_ul(module_id, + frame, + slot, + num_slots_per_tdd, + &UE_info->list, + len, + rballoc_mask, + 2); + return true; +} + +void nr_schedule_ulsch(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + int ul_slots, + uint64_t ulsch_in_slot_bitmap) { + /* Uplink data ONLY can be scheduled when the current slot is downlink slot, + * because we have to schedule the DCI0 first before schedule uplink data */ + if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot)) { + LOG_D(MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot); + return; + } + bool do_sched = RC.nrmac[module_id]->pre_processor_ul( + module_id, frame, slot, num_slots_per_tdd, ulsch_in_slot_bitmap); + if (!do_sched) + return; + + const int CC_id = 0; + nfapi_nr_ul_dci_request_t *ul_dci_req = &RC.nrmac[module_id]->UL_dci_req[CC_id]; + ul_dci_req->SFN = frame; + ul_dci_req->Slot = slot; + /* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each + * allocated PDCCH so we can easily allocate UE's DCIs independent of any + * CORESET order */ + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {0}; + + NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + const NR_list_t *UE_list = &UE_info->list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + UE_info->mac_stats[UE_id].ulsch_current_bytes = 0; + /* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in + * every TTI are pre-populated by the preprocessor and used below */ + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + if (sched_pusch->rbSize <= 0) + continue; + + uint16_t rnti = UE_info->rnti[UE_id]; + + int8_t harq_id = sched_pusch->ul_harq_pid; + if (harq_id < 0) { + /* PP has not selected a specific HARQ Process, get a new one */ + harq_id = sched_ctrl->available_ul_harq.head; + AssertFatal(harq_id >= 0, + "no free HARQ process available for UE %d\n", + UE_id); + remove_front_nr_list(&sched_ctrl->available_ul_harq); + sched_pusch->ul_harq_pid = harq_id; + } else { + /* PP selected a specific HARQ process. Check whether it will be a new + * transmission or a retransmission, and remove from the corresponding + * list */ + if (sched_ctrl->ul_harq_processes[harq_id].round == 0) + remove_nr_list(&sched_ctrl->available_ul_harq, harq_id); + else + remove_nr_list(&sched_ctrl->retrans_ul_harq, harq_id); + } + NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[harq_id]; + DevAssert(!cur_harq->is_waiting); + add_tail_nr_list(&sched_ctrl->feedback_ul_harq, harq_id); + cur_harq->feedback_slot = sched_pusch->slot; + cur_harq->is_waiting = true; + + int rnti_types[2] = { NR_RNTI_C, 0 }; + + /* pre-computed PUSCH values that only change if time domain allocation, + * DCI format, or DMRS parameters change. Updated in the preprocessor + * through nr_save_pusch_fields() */ + NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save; + + /* Statistics */ + UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; + if (cur_harq->round == 0) { + UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size; + /* Save information on MCS, TBS etc for the current initial transmission + * so we have access to it when retransmitting */ + cur_harq->sched_pusch = *sched_pusch; + } else { + LOG_D(MAC, + "%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n", + frame, + slot, + rnti, + sched_pusch->frame, + sched_pusch->slot, + harq_id, + cur_harq->round, + cur_harq->ndi); + } + UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size; + sched_ctrl->sched_ul_bytes += sched_pusch->tb_size; + + LOG_D(MAC, + "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n", + frame, + slot, + rnti, + sched_pusch->frame, + sched_pusch->slot, + sched_pusch->rbStart, + sched_pusch->rbSize, + sched_pusch->mcs, + sched_pusch->tb_size, + harq_id, + cur_harq->round, + cur_harq->ndi); + + /* PUSCH in a later slot, but corresponding DCI now! */ + nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][sched_pusch->slot]; + AssertFatal(future_ul_tti_req->SFN == sched_pusch->frame + && future_ul_tti_req->Slot == sched_pusch->slot, + "%d.%d future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n", + frame, slot, + future_ul_tti_req->SFN, + future_ul_tti_req->Slot, + sched_pusch->frame, + sched_pusch->slot); + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; + memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); + future_ul_tti_req->n_pdus += 1; + + LOG_D(MAC, "%4d.%2d Scheduling UE specific PUSCH\n", frame, slot); + + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = rnti; + pusch_pdu->handle = 0; //not yet used + + /* FAPI: BWP */ + pusch_pdu->bwp_size = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pusch_pdu->bwp_start = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + pusch_pdu->subcarrier_spacing = sched_ctrl->active_ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_pdu->cyclic_prefix = 0; + + /* FAPI: PUSCH information always included */ + pusch_pdu->target_code_rate = sched_pusch->R; + pusch_pdu->qam_mod_order = sched_pusch->Qm; + pusch_pdu->mcs_index = sched_pusch->mcs; + pusch_pdu->mcs_table = ps->mcs_table; + pusch_pdu->transform_precoding = ps->transform_precoding; + if (ps->pusch_Config->dataScramblingIdentityPUSCH) + pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; + else + pusch_pdu->data_scrambling_id = *scc->physCellId; + pusch_pdu->nrOfLayers = 1; + + /* FAPI: DMRS */ + pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos; + pusch_pdu->dmrs_config_type = ps->dmrs_config_type; + if (pusch_pdu->transform_precoding) { // transform precoding disabled + long *scramblingid; + if (pusch_pdu->scid == 0) + scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0; + else + scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1; + if (scramblingid == NULL) + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; + else + pusch_pdu->ul_dmrs_scrambling_id = *scramblingid; + } + else { + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; + if (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL) + pusch_pdu->pusch_identity = *ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity; + else + pusch_pdu->pusch_identity = *scc->physCellId; + } + pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1] + pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data; + pusch_pdu->dmrs_ports = 1; + + /* FAPI: Pusch Allocation in frequency domain */ + AssertFatal(ps->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); + pusch_pdu->resource_alloc = 1; //type 1 + pusch_pdu->rb_start = sched_pusch->rbStart; + pusch_pdu->rb_size = sched_pusch->rbSize; + pusch_pdu->vrb_to_prb_mapping = 0; + if (ps->pusch_Config->frequencyHopping==NULL) + pusch_pdu->frequency_hopping = 0; + else + pusch_pdu->frequency_hopping = 1; + + /* FAPI: Resource Allocation in time domain */ + pusch_pdu->start_symbol_index = ps->startSymbolIndex; + pusch_pdu->nr_of_symbols = ps->nrOfSymbols; + + /* PUSCH PDU */ + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round]; + pusch_pdu->pusch_data.harq_process_id = harq_id; + pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi; + pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size; + pusch_pdu->pusch_data.num_cb = 0; //CBG not supported + + /* TRANSFORM PRECODING --------------------------------------------------------*/ + + if (pusch_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled){ + + // U as specified in section 6.4.1.1.1.2 in 38.211, if sequence hopping and group hopping are disabled + pusch_pdu->dfts_ofdm.low_papr_group_number = pusch_pdu->pusch_identity % 30; + + // V as specified in section 6.4.1.1.1.2 in 38.211 V = 0 if sequence hopping and group hopping are disabled + if ((ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping == NULL) && + (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping == NULL)) + pusch_pdu->dfts_ofdm.low_papr_sequence_number = 0; + else + AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); + + LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d MCS table: %d\n", pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dfts_ofdm.low_papr_group_number, ps->mcs_table); + } + + /*-----------------------------------------------------------------------------*/ + + /* PUSCH PTRS */ + if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) { + // TODO to be fixed from RRC config + uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig + uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig + uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig + uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig + uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig + pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table); + pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size); + pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); + pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + + pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS + } + else{ + pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + } + + /* look up the PDCCH PDU for this BWP and CORESET. If it does not exist, + * create it */ + const int bwpid = sched_ctrl->active_bwp->bwp_Id; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = pdcch_pdu_bwp_coreset[bwpid][coresetid]; + if (!pdcch_pdu) { + nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus]; + memset(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)); + pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; + ul_dci_req->numPdus += 1; + nr_configure_pdcch(pdcch_pdu, sched_ctrl->search_space, sched_ctrl->coreset, scc, sched_ctrl->active_bwp); + pdcch_pdu_bwp_coreset[bwpid][coresetid] = pdcch_pdu; + } + + LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frame,slot); + + /* Fill PDCCH DL DCI PDU */ + nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci]; + pdcch_pdu->numDlDci++; + dci_pdu->RNTI = rnti; + if (sched_ctrl->coreset->pdcch_DMRS_ScramblingID && + sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { + dci_pdu->ScramblingId = *sched_ctrl->coreset->pdcch_DMRS_ScramblingID; + dci_pdu->ScramblingRNTI = rnti; + } else { + dci_pdu->ScramblingId = *scc->physCellId; + dci_pdu->ScramblingRNTI = 0; + } + dci_pdu->AggregationLevel = sched_ctrl->aggregation_level; + dci_pdu->CceIndex = sched_ctrl->cce_index; + dci_pdu->beta_PDCCH_1_0 = 0; + dci_pdu->powerControlOffsetSS = 1; + + dci_pdu_rel15_t uldci_payload; + memset(&uldci_payload, 0, sizeof(uldci_payload)); + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; + const int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; + config_uldci(sched_ctrl->active_ubwp, + pusch_pdu, + &uldci_payload, + ps->dci_format, + ps->time_domain_allocation, + UE_info->UE_sched_ctrl[UE_id].tpc0, + n_ubwp, + sched_ctrl->active_bwp->bwp_Id); + fill_dci_pdu_rel15(scc, + secondaryCellGroup, + dci_pdu, + &uldci_payload, + ps->dci_format, + rnti_types[0], + pusch_pdu->bwp_size, + sched_ctrl->active_bwp->bwp_Id); + + memset(sched_pusch, 0, sizeof(*sched_pusch)); + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 2875dcebc1..046ab9a9e4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -64,23 +64,39 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP); -int nr_generate_dlsch_pdu(module_id_t Mod_idP, - NR_UE_sched_ctrl_t *ue_sched_ctl, - unsigned char *sdus_payload, - unsigned char *mac_pdu, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned char *ue_cont_res_id, - unsigned short post_padding); - void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, - sub_frame_t slot, - int num_slots_per_tdd); + sub_frame_t slot); -void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); +void schedule_control_sib1(module_id_t module_id, + int CC_id, + int time_domain_allocation, + uint8_t mcsTableIdx, + uint8_t mcs, + int num_total_bytes); + +void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); + +/* \brief default preprocessor */ +void nr_simple_dlsch_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot); + +void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame); + +/// uplink scheduler +void nr_schedule_ulsch(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + int ul_slots, + uint64_t ulsch_in_slot_bitmap); + +bool nr_simple_ulsch_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + uint64_t ulsch_in_slot_bitmap); /////// Random Access MAC-PHY interface functions and primitives /////// @@ -101,7 +117,9 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP); int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only); -void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc, +void nr_get_Msg3alloc(module_id_t module_id, + int CC_id, + NR_ServingCellConfigCommon_t *scc, NR_BWP_Uplink_t *ubwp, sub_frame_t current_subframe, frame_t current_frame, @@ -124,80 +142,43 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs); /////// Phy test scheduler /////// +/* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all + * freq resources */ +void nr_preprocessor_phytest(module_id_t module_id, + frame_t frame, + sub_frame_t slot); +/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a + * fixed set of resources */ +bool nr_ul_preprocessor_phytest(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + uint64_t ulsch_in_slot_bitmap); + void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); -void nr_fill_nfapi_dl_pdu(int Mod_id, - int UE_id, - int bwp_id, - NR_SearchSpace_t *ss, - NR_ControlResourceSet_t *coreset, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - int nrOfLayers, - uint8_t mcs, - uint16_t rbSize, - uint16_t rbStart, - uint8_t numDmrsCdmGrpsNoData, - nfapi_nr_dmrs_type_e dmrsConfigType, - uint8_t table_idx, - uint16_t R, - uint8_t Qm, - uint32_t tbs, - int time_domain_assignment, - int StartSymbolIndex, - int NrOfSymbols, - uint8_t aggregation_level, - int CCEIndex, - int harq_pid, - int ndi, - int round); +void handle_nr_uci_pucch_0_1(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01); +void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234); -int configure_fapi_dl_pdu_phytest(int Mod_id, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - uint8_t *mcsIndex, - uint16_t *rbSize, - uint16_t *rbStart); -void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch, - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01, - nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234, - NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats); - -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, +void config_uldci(const NR_BWP_Uplink_t *ubwp, + const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int *dci_formats, int *rnti_types, - int time_domain_assignment, uint8_t tpc, - int n_ubwp, int bwp_id); - -void configure_fapi_dl_Tx(module_id_t Mod_idP, - frame_t frameP, - sub_frame_t slotP, - nfapi_nr_dl_tti_request_body_t *dl_req, - nfapi_nr_pdu_t *tx_req, - int tbs_bytes, - int16_t pdu_index); - -void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, - frame_t frameP, - sub_frame_t slotP, - NR_sched_pucch *pucch_sched, - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); - -void nr_schedule_pusch(int Mod_idP, - int UE_id, - int num_slots_per_tdd, - int ul_slots, - frame_t frameP, - sub_frame_t slotP); + int dci_format, + int time_domain_assignment, + uint8_t tpc, + int n_ubwp, + int bwp_id); void nr_schedule_pucch(int Mod_idP, - int UE_id, - int nr_ulmix_slots, frame_t frameP, sub_frame_t slotP); @@ -212,26 +193,13 @@ void csi_period_offset(NR_CSI_ReportConfig_t *csirep, int *period, int *offset); void nr_csi_meas_reporting(int Mod_idP, + frame_t frameP, + sub_frame_t slotP); + +bool nr_acknack_scheduling(int Mod_idP, int UE_id, frame_t frameP, - sub_frame_t slotP, - int slots_per_tdd, - int ul_slots, - int n_slots_frame); - -void csi_period_offset(NR_CSI_ReportConfig_t *csirep, - NR_NZP_CSI_RS_Resource_t *nzpcsi, - int *period, int *offset); - -void nr_acknack_scheduling(int Mod_idP, - int UE_id, - frame_t frameP, - sub_frame_t slotP, - int slots_per_tdd, - int *pucch_id, - int *pucch_occ); - -int get_pucch_resource(NR_UE_info_t *UE_info,int UE_id,int k,int l); + sub_frame_t slotP); void get_pdsch_to_harq_feedback(int Mod_idP, int UE_id, @@ -270,26 +238,22 @@ void find_search_space(int ss_type, NR_BWP_Downlink_t *bwp, NR_SearchSpace_t *ss); -void nr_configure_pdcch(gNB_MAC_INST *nr_mac, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, - uint16_t rnti, +void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Downlink_t *bwp, - uint8_t aggregation_level, - int CCEIndex); + NR_BWP_Downlink_t *bwp); -void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *secondaryCellGroup, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, +void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, + const NR_CellGroupConfig_t *secondaryCellGroup, + nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int *dci_formats, - int *rnti_types, + int dci_formats, + int rnti_types, int N_RB, int bwp_id); -void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, +void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu_rel15, nr_dci_format_t format, int bwp_id); @@ -304,9 +268,15 @@ NR_SearchSpace_t *get_searchspace( NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss); -void find_aggregation_candidates(uint8_t *aggregation_level, - uint8_t *nr_of_candidates, - NR_SearchSpace_t *ss); + +long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu); + +void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc, + const NR_BWP_Uplink_t *ubwp, + long dci_format, + int tda, + uint8_t num_dmrs_cdm_grps_no_data, + NR_sched_pusch_save_t *ps); uint8_t nr_get_tpc(int target, uint8_t cqi, int incr); @@ -330,12 +300,21 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); -void dump_nr_ue_list(NR_UE_list_t *listP); -void add_nr_ue_list(NR_UE_list_t *listP, int UE_id); +/* Functions to manage an NR_list_t */ +void dump_nr_list(NR_list_t *listP); +void create_nr_list(NR_list_t *listP, int len); +void destroy_nr_list(NR_list_t *list); +void add_nr_list(NR_list_t *listP, int id); +void remove_nr_list(NR_list_t *listP, int id); +void add_tail_nr_list(NR_list_t *listP, int id); +void add_front_nr_list(NR_list_t *listP, int id); +void remove_front_nr_list(NR_list_t *listP); int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP); -int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP); +int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); + +int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup); void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti); @@ -343,8 +322,9 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, NR_BWP_Downlink_t *bwp, NR_ControlResourceSet_t *coreset, int aggregation, - uint16_t n_RNTI, - int m); + uint16_t Y, + int m, + int nr_of_candidates); uint16_t compute_pucch_prb_size(uint8_t format, uint8_t nr_prbs, @@ -363,8 +343,6 @@ int get_ulscs(nfapi_nr_config_request_t *cfg); int get_symbolsperslot(nfapi_nr_config_request_t *cfg); -int32_t get_nr_uldl_offset(int nr_bandP); - void config_nr_mib(int Mod_idP, int CC_idP, int p_gNBP, @@ -381,16 +359,6 @@ void nr_generate_Msg2(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); -void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP); - -void schedule_fapi_ul_pdu(int Mod_idP, - frame_t frameP, - sub_frame_t slotP, - int num_slots_per_tdd, - int ul_slots, - int time_domain_assignment, - uint64_t ulsch_in_slot_bitmap); - void nr_process_mac_pdu( module_id_t module_idP, rnti_t rnti, @@ -403,6 +371,8 @@ int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id); + /* \brief Function to indicate a received SDU on ULSCH. @param Mod_id Instance ID of gNB @@ -424,7 +394,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint8_t ul_cqi, const uint16_t rssi); -void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu); +void handle_nr_ul_harq(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + const nfapi_nr_crc_t *crc_pdu); -void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10); +int16_t ssb_index_from_prach(module_id_t module_idP, + frame_t frameP, + sub_frame_t slotP, + uint16_t preamble_index, + uint8_t freq_index, + uint8_t symbol); + +void find_SSB_and_RO_available(module_id_t module_idP); + +bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id); #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 7df00f15f1..8dc1303801 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -34,7 +34,6 @@ #include "NR_MAC_COMMON/nr_mac_extern.h" #include "assertions.h" -#include "LAYER2/PDCP_v10.1.0/pdcp.h" #include "LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "RRC/NR/nr_rrc_defs.h" #include "common/utils/LOG/log.h" @@ -82,6 +81,14 @@ void mac_top_init_gNB(void) RC.nrmac[i]->ul_handle = 0; + if (get_softmodem_params()->phy_test) { + RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; + RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest; + } else { + RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor; + RC.nrmac[i]->pre_processor_ul = nr_simple_ulsch_preprocessor; + } + }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); @@ -89,8 +96,8 @@ void mac_top_init_gNB(void) // These should be out of here later pdcp_layer_init(); - if(IS_SOFTMODEM_NOS1) - nr_DRB_preconfiguration(); + if(IS_SOFTMODEM_NOS1 && !get_softmodem_params()->do_ra) + nr_DRB_preconfiguration(0x1234); rrc_init_nr_global_param(); @@ -106,18 +113,9 @@ void mac_top_init_gNB(void) UE_info = &nrmac->UE_info; UE_info->num_UEs = 0; - UE_info->list.head = -1; + create_nr_list(&UE_info->list, MAX_MOBILES_PER_GNB); for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) { - UE_info->list.next[list_el] = -1; UE_info->active[list_el] = false; - for (int list_harq = 0; list_harq < NR_MAX_NB_HARQ_PROCESSES; list_harq++) { - UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0; - UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0; - UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0; - UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0; - UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0; - UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0; - } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index fcfcd3ef0f..bca974a00f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -68,12 +68,26 @@ #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" #include "NR_TAG.h" +#include + + /* Defs */ #define MAX_NUM_BWP 2 #define MAX_NUM_CORESET 2 #define MAX_NUM_CCE 90 +#define MAX_HARQ_ROUNDS 4 /*!\brief Maximum number of random access process */ #define NR_NB_RA_PROC_MAX 4 +#define MAX_NUM_OF_SSB 64 + +/*! \brief NR_list_t is a "list" (of users, HARQ processes, slices, ...). + * Especially useful in the scheduler and to keep "classes" of users. */ +typedef struct { + int head; + int *next; + int tail; + int len; +} NR_list_t; typedef enum { RA_IDLE = 0, @@ -138,20 +152,22 @@ typedef struct { uint8_t msg3_cqireq; /// Round of Msg3 HARQ uint8_t msg3_round; - /// Msg3 pusch pdu - nfapi_nr_pusch_pdu_t pusch_pdu; /// TBS used for Msg4 int msg4_TBsize; /// MCS used for Msg4 int msg4_mcs; /// RA search space NR_SearchSpace_t *ra_ss; + // Beam index + uint8_t beam_id; /// secondaryCellGroup for UE in NSA that is to come NR_CellGroupConfig_t *secondaryCellGroup; /// Preambles for contention-free access NR_preamble_ue_t preambles; /// NSA: the UEs C-RNTI to use rnti_t crnti; + /// CFRA flag + bool cfra; } NR_RA_t; /*! \brief gNB common channels */ @@ -183,11 +199,22 @@ typedef struct { /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels - uint8_t vrb_map[275]; - /// VRB map for common channels and retransmissions by PHICH - uint8_t vrb_map_UL[275]; + uint16_t vrb_map[275]; + /// VRB map for common channels and PUSCH, dynamically allocated because + /// length depends on number of slots and RBs + uint16_t *vrb_map_UL; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; + ///Number of active SSBs + uint8_t num_active_ssb; + //Total available prach occasions per configuration period + uint32_t total_prach_occasions_per_config_period; + //Total available prach occasions + uint32_t total_prach_occasions; + //Max Association period + uint8_t max_association_period; + //SSB index + uint8_t ssb_index[MAX_NUM_OF_SSB]; } NR_COMMON_channels_t; @@ -265,20 +292,64 @@ typedef struct NR_sched_pucch { uint8_t dai_c; uint8_t timing_indicator; uint8_t resource_indicator; -} NR_sched_pucch; +} NR_sched_pucch_t; + +/* this struct is a helper: as long as the TDA and DCI format remain the same + * over the same uBWP and search space, there is no need to recalculate all + * S/L, MCS table, or DMRS-related parameters over and over again. Hence, we + * store them in this struct for easy reference. */ +typedef struct NR_sched_pusch_save { + int dci_format; + int time_domain_allocation; + uint8_t num_dmrs_cdm_grps_no_data; + + int startSymbolIndex; + int nrOfSymbols; + + NR_PUSCH_Config_t *pusch_Config; + uint8_t transform_precoding; + uint8_t mcs_table; + + long mapping_type; + NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; + uint16_t dmrs_config_type; + uint16_t ul_dmrs_symb_pos; + uint8_t num_dmrs_symb; + uint8_t N_PRB_DMRS; +} NR_sched_pusch_save_t; typedef struct NR_sched_pusch { int frame; int slot; - bool active; - nfapi_nr_pusch_pdu_t pusch_pdu; -} NR_sched_pusch; + + /// RB allocation within active uBWP + uint16_t rbSize; + uint16_t rbStart; + + // time-domain allocation for scheduled RBs + int time_domain_allocation; + + /// MCS + uint8_t mcs; + + /// TBS-related info + uint16_t R; + uint8_t Qm; + uint32_t tb_size; + + /// UL HARQ PID to use for this UE, or -1 for "any new" + int8_t ul_harq_pid; +} NR_sched_pusch_t; typedef struct NR_UE_harq { - uint8_t is_waiting; + bool is_waiting; uint8_t ndi; uint8_t round; uint16_t feedback_slot; + + /* Transport block to be sent using this HARQ process */ + uint32_t tb[16384]; + uint32_t tb_size; } NR_UE_harq_t; typedef struct NR_UE_old_sched { @@ -296,10 +367,13 @@ typedef enum { } NR_UL_harq_states_t; typedef struct NR_UE_ul_harq { + bool is_waiting; uint8_t ndi; uint8_t round; - uint16_t last_tx_slot; - NR_UL_harq_states_t state; + uint16_t feedback_slot; + + /// sched_pusch keeps information on MCS etc used for the initial transmission + NR_sched_pusch_t sched_pusch; } NR_UE_ul_harq_t; @@ -330,11 +404,17 @@ typedef struct { /// the currently active BWP in DL NR_BWP_Downlink_t *active_bwp; - NR_sched_pucch **sched_pucch; - /// selected PUCCH index, if scheduled - int pucch_sched_idx; - int pucch_occ_idx; - NR_sched_pusch *sched_pusch; + /// the currently active BWP in UL + NR_BWP_Uplink_t *active_ubwp; + + /// PUCCH scheduling information. Array of three, we assume for the moment: + /// HARQ in the first field, SR in second, CSI in third (as fixed by RRC + /// conf., i.e. if actually present). The order is important for + /// nr_acknack_scheduling()! + NR_sched_pucch_t sched_pucch[3]; + + NR_sched_pusch_save_t pusch_save; + NR_sched_pusch_t sched_pusch; /// CCE index and aggregation, should be coherent with cce_list NR_SearchSpace_t *search_space; @@ -346,6 +426,11 @@ typedef struct { uint16_t rbSize; uint16_t rbStart; + /// uplink bytes that are currently scheduled + int sched_ul_bytes; + /// estimation of the UL buffer size + int estimated_ul_buffer; + // time-domain allocation for scheduled RBs int time_domain_allocation; @@ -356,56 +441,85 @@ typedef struct { /// Retransmission-related information NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES]; + /// DL HARQ PID to use for this UE, or -1 for "any new" + int8_t dl_harq_pid; - uint16_t ta_timer; + uint16_t ta_frame; int16_t ta_update; bool ta_apply; uint8_t tpc0; uint8_t tpc1; uint16_t ul_rssi; - uint8_t current_harq_pid; + /// information about every HARQ process NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; + /// HARQ processes that are free + NR_list_t available_dl_harq; + /// HARQ processes that await feedback + NR_list_t feedback_dl_harq; + /// HARQ processes that await retransmission + NR_list_t retrans_dl_harq; + /// information about every UL HARQ process NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES]; + /// UL HARQ processes that are free + NR_list_t available_ul_harq; + /// UL HARQ processes that await feedback + NR_list_t feedback_ul_harq; + /// UL HARQ processes that await retransmission + NR_list_t retrans_ul_harq; int dummy; NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information } NR_UE_sched_ctrl_t; typedef struct { + boolean_t fiveG_connected; + uicc_t *uicc; +} NRUEcontext_t; +typedef struct { int lc_bytes_tx[64]; int lc_bytes_rx[64]; int dlsch_rounds[8]; int dlsch_errors; int dlsch_total_bytes; + int dlsch_current_bytes; int ulsch_rounds[8]; int ulsch_errors; int ulsch_total_bytes_scheduled; int ulsch_total_bytes_rx; + int ulsch_current_bytes; } NR_mac_stats_t; -/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in - * the scheduler and to keep "classes" of users. */ -typedef struct { - int head; - int next[MAX_MOBILES_PER_GNB]; -} NR_UE_list_t; - /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ #define MAX_CSI_REPORTCONFIG 48 typedef struct { - DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB]; /// scheduling control info nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG]; NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; - NR_UE_list_t list; + NR_list_t list; int num_UEs; + bool active[MAX_MOBILES_PER_GNB]; rnti_t rnti[MAX_MOBILES_PER_GNB]; NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB]; + /// CCE indexing + int Y[MAX_MOBILES_PER_GNB][3][160]; + int m[MAX_MOBILES_PER_GNB]; + int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET]; + // UE selected beam index + uint8_t UE_beam_index[MAX_MOBILES_PER_GNB]; } NR_UE_info_t; +typedef void (*nr_pp_impl_dl)(module_id_t mod_id, + frame_t frame, + sub_frame_t slot); +typedef bool (*nr_pp_impl_ul)(module_id_t mod_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd, + uint64_t ulsch_in_slot_bitmap); + /*! \brief top level eNB MAC structure */ typedef struct gNB_MAC_INST_s { /// Ethernet parameters for northbound midhaul interface @@ -431,8 +545,16 @@ typedef struct gNB_MAC_INST_s { nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX]; /// NFAPI DL Config Request Structure 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]; + /// a PDCCH PDU groups DCIs per BWP and CORESET. The following structure + /// keeps pointers to PDCCH PDUs within DL_req so that we can easily track + /// PDCCH PDUs per CC/BWP/CORESET + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_idx[NFAPI_CC_MAX][MAX_NUM_BWP][MAX_NUM_CORESET]; + /// NFAPI UL TTI Request Structure, simple pointer into structure + /// UL_tti_req_ahead for current frame/slot + nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX]; + /// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated + /// because length depends on number of slots + nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX]; /// NFAPI HI/DCI0 Config Request Structure nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX]; /// NFAPI DL PDU structure @@ -442,6 +564,7 @@ typedef struct gNB_MAC_INST_s { /// UL handle uint32_t ul_handle; + //UE_info_t UE_info; // MAC function execution peformance profiler /// processing time of eNB scheduler @@ -466,6 +589,20 @@ typedef struct gNB_MAC_INST_s { time_stats_t schedule_pch; /// CCE lists int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE]; + /// PUCCH: keep track of the resources has already been used by saving the + /// highest index not yet been used in a given slot. Dynamically allocated + /// so we can have it for every slot as a function of the numerology + int *pucch_index_used[MAX_NUM_BWP]; + + /// DL preprocessor for differentiated scheduling + nr_pp_impl_dl pre_processor_dl; + /// UL preprocessor for differentiated scheduling + nr_pp_impl_ul pre_processor_ul; + + NR_UE_sched_ctrl_t *sched_ctrlCommon; + NR_CellGroupConfig_t *secondaryCellGroupCommon; + NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config; + } gNB_MAC_INST; #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 33f268f07f..8196d2b1fc 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -358,16 +358,7 @@ boolean_t pdcp_data_req( 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); - // 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 + if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(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 { @@ -403,7 +394,7 @@ boolean_t pdcp_data_req( // DL transfer MessageDef *message_p; // Note: the acyual task must be TASK_PDCP_ENB, but this task is not created - message_p = itti_alloc_new_message (TASK_PDCP_ENB, F1AP_DL_RRC_MESSAGE); + message_p = itti_alloc_new_message (TASK_PDCP_ENB, 0, F1AP_DL_RRC_MESSAGE); F1AP_DL_RRC_MESSAGE (message_p).rrc_container = &pdcp_pdu_p->data[0] ; F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = pdcp_pdu_size; F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; @@ -939,7 +930,7 @@ pdcp_data_ind( sdu_buffer_sizeP - payload_offset + GTPU_HEADER_OVERHEAD_MAX); AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset); - message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ); + message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ); AssertFatal(message_p != NULL, "OUT OF MEMORY"); GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = sdu_buffer_sizeP - payload_offset; @@ -996,17 +987,7 @@ pdcp_data_ind( * TODO: be sure of this */ if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) { -#ifdef UESIM_EXPANSION - - if (UE_NAS_USE_TUN) { - pdcpHead->inst = ctxt_pP->module_id; - } else { - pdcpHead->inst = 0; - } - -#else pdcpHead->inst = ctxt_pP->module_id; -#endif } else { // nfapi_mode if (UE_NAS_USE_TUN) { pdcpHead->inst = ctxt_pP->module_id; @@ -1035,7 +1016,7 @@ pdcp_data_ind( pushNotifiedFIFO(&pdcp_sdu_list, new_sdu_p); /* Print octets of incoming data in hexadecimal form */ - LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", + LOG_D(PDCP, "Following content has been received from RLC (%d,%d)(PDCP header has already been removed):\n", sdu_buffer_sizeP - payload_offset + (int)sizeof(pdcp_data_ind_header_t), sdu_buffer_sizeP - payload_offset); //util_print_hex_octets(PDCP, &new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], sdu_buffer_sizeP - payload_offset); @@ -1158,11 +1139,11 @@ 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 %ld, muiP %d, confirmP %d, mode %d\n", + LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %ld, 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), - ITTI_MSG_INSTANCE (msg_p), + ITTI_MSG_DESTINATION_INSTANCE (msg_p), RRC_DCCH_DATA_REQ (msg_p).rb_id, RRC_DCCH_DATA_REQ (msg_p).muip, RRC_DCCH_DATA_REQ (msg_p).confirmp, @@ -1284,7 +1265,7 @@ pdcp_mbms_run ( // PROTOCOL_CTXT_ARGS(&ctxt), // ITTI_MSG_NAME (msg_p), // ITTI_MSG_ORIGIN_NAME(msg_p), -// ITTI_MSG_INSTANCE (msg_p), +// ITTI_MSG_DESTINATION_INSTANCE (msg_p), // RRC_DCCH_DATA_REQ (msg_p).rb_id, // RRC_DCCH_DATA_REQ (msg_p).muip, // RRC_DCCH_DATA_REQ (msg_p).confirmp, @@ -2287,7 +2268,7 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { nas_getparams(); if(UE_NAS_USE_TUN) { - int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1; netlink_init_tun("ue",num_if); if (IS_SOFTMODEM_NOS1) nas_config(1, 1, 2, "ue"); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index de8a1b385b..c8ab4499ee 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -53,9 +53,6 @@ typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *cons typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_flag_t, const MBMS_flag_t, const rb_id_t, const sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); -/* maximum number of tun interfaces that will be created to emulates UEs */ -/* UEs beyond that will be multiplexed on the same tun */ -#define MAX_NUMBER_NETIF 16 #define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10) #define PDCP_USE_NETLINK_BIT (1<< 11) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index c9a62d573b..687d7b1bfe 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -86,12 +86,6 @@ extern struct msghdr nas_msg_rx; -#ifdef UESIM_EXPANSION - extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif - - - # include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_defs.h" @@ -156,9 +150,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { nas_nlh_tx->nlmsg_len = sizeToWrite; ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0); } // PDCP_USE_NETLINK - - AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]); + AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]); + if( LOG_DEBUGFLAG(DEBUG_PDCP) ) log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR, "Printing first bytes of PDCP SDU before removing it from the list: \n"); @@ -202,6 +196,7 @@ int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) { //} // PDCP_USE_NETLINK //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); + //AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno)); delNotifiedFIFO_elt (sdu_p); pdcp_nb_sdu_sent ++; @@ -242,9 +237,9 @@ 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 %ld \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %ld: 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 %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %ld][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); @@ -263,7 +258,7 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { ); } else { LOG_D(PDCP, - "[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", + "[FRAME %5u][UE][IP][INSTANCE %ld][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); } @@ -310,9 +305,9 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p 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 %ld \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %ld: 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 %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %ld][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, @@ -349,7 +344,7 @@ int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_p MSC_AS_TIME_ARGS(ctxt_pP), ctxt.instance, rab_id, rab_id, len); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %ld][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); //if (!UE_NAS_USE_TUN) { @@ -503,11 +498,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx } } else { // ctxt.enb_flag => UE if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { -#ifdef UESIM_EXPANSION - ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst]; -#else ctxt.module_id = pdcp_read_header_g.inst; -#endif } else { ctxt.module_id = 0; } diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c index 6e343343cd..bf6579955b 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c @@ -535,7 +535,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 %ld, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP); + LOG_D(PROTO_AGENT, "[inst %ld] 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/rlc.h b/openair2/LAYER2/RLC/rlc.h index 27ca18ed7e..7e4920a579 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -143,7 +143,7 @@ void (*rlc_rrc_data_conf)( const protocol_ctxt_t *const ctxtP, const rb_id_t rb_idP, const mui_t muiP, - const rlc_tx_status_t statusP); + const rlc_tx_status_t statusP) __attribute__ ((aligned(32))); typedef void (rrc_data_ind_cb_t)( const protocol_ctxt_t *const ctxtP, diff --git a/openair2/LAYER2/nr_pdcp/asn1_utils.c b/openair2/LAYER2/nr_pdcp/asn1_utils.c new file mode 100644 index 0000000000..264a2815bb --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/asn1_utils.c @@ -0,0 +1,68 @@ +/* + * 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 "pdcp.h" + +int decode_t_reordering(int v) +{ + static int tab[36] = { + 0, 1, 2, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, 180, + 200, 220, 240, 260, 280, 300, 500, 750, 1000, 1250, 1500, 1750, 2000, + 2250, 2500, 2750, 3000 + }; + + if (v < 0 || v > 35) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_sn_size_ul(long s) +{ + if (s == 0) return 12; + if (s == 1) return 18; + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); +} + +int decode_sn_size_dl(long s) +{ + if (s == 0) return 12; + if (s == 1) return 18; + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); +} + +int decode_discard_timer(long v) +{ + static int tab[16] = { + 10, 20, 30, 40, 50, 60, 75, 100, 150, 200, 250, 300, 500, 750, 1500, -1, + }; + + if (v < 0 || v > 15) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} diff --git a/common/utils/itti_analyzer/libbuffers/file.h b/openair2/LAYER2/nr_pdcp/asn1_utils.h similarity index 79% rename from common/utils/itti_analyzer/libbuffers/file.h rename to openair2/LAYER2/nr_pdcp/asn1_utils.h index be0fa6ba2d..d525bce287 100644 --- a/common/utils/itti_analyzer/libbuffers/file.h +++ b/openair2/LAYER2/nr_pdcp/asn1_utils.h @@ -19,9 +19,12 @@ * contact@openairinterface.org */ -#ifndef FILE_H_ -#define FILE_H_ +#ifndef _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ +#define _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ -int file_read_dump(buffer_t **buffer, const char *filename); +int decode_t_reordering(int v); +int decode_sn_size_ul(long s); +int decode_sn_size_dl(long s); +int decode_discard_timer(long v); -#endif /* FILE_H_ */ +#endif /* _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index e25201c22c..f3d4b16130 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -44,7 +44,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_sdu_data, void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, int sdu_id), - void *deliver_pdu_data) + void *deliver_pdu_data, + int sn_size, + int t_reordering, + int discard_timer) { nr_pdcp_entity_drb_am_t *ret; @@ -66,9 +69,12 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( ret->common.deliver_pdu = deliver_pdu; ret->common.deliver_pdu_data = deliver_pdu_data; - ret->rb_id = rb_id; + ret->rb_id = rb_id; + ret->sn_size = sn_size; + ret->t_reordering = t_reordering; + ret->discard_timer = discard_timer; - ret->common.maximum_nr_pdcp_sn = 4095; + ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1; return (nr_pdcp_entity_t *)ret; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 45555ad6af..ce5dd300e9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -19,6 +19,8 @@ * contact@openairinterface.org */ +#include + #ifndef _NR_PDCP_ENTITY_H_ #define _NR_PDCP_ENTITY_H_ @@ -58,8 +60,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( void *deliver_sdu_data, void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, char *buf, int size, int sdu_id), - void *deliver_pdu_data); + void *deliver_pdu_data, + int sn_size, + int t_reordering, + int discard_timer); -void nr_DRB_preconfiguration(void); +void nr_DRB_preconfiguration(uint16_t crnti); #endif /* _NR_PDCP_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c index 85f638d66d..f2f849b9e3 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c @@ -24,13 +24,17 @@ #include #include #include +#include "common/utils/LOG/log.h" void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size) { nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; if (size < 3) abort(); - if (!(buffer[0] & 0x80)) { printf("%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } + + if (!(buffer[0] & 0x80)) + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + entity->common.deliver_sdu(entity->common.deliver_sdu_data, (nr_pdcp_entity_t *)entity, buffer+3, size-3); } @@ -40,7 +44,7 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int { nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; int sn; - char buf[size+2]; + char buf[size+3]; sn = entity->common.next_nr_pdcp_tx_sn; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h index faa8226e93..d7c42e6a62 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h @@ -27,6 +27,9 @@ typedef struct { nr_pdcp_entity_t common; int rb_id; + int sn_size; /* unit: bits */ + int t_reordering; /* unit: ms */ + int discard_timer; /* unit: ms, -1 means infinity */ } nr_pdcp_entity_drb_am_t; void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 0d98840f5b..6195a91ea2 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -19,14 +19,20 @@ * contact@openairinterface.org */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "asn1_utils.h" #include "nr_pdcp_ue_manager.h" #include "NR_RadioBearerConfig.h" #include "NR_RLC-BearerConfig.h" +#include "NR_RLC-Config.h" #include "NR_CellGroupConfig.h" #include "openair2/RRC/NR/nr_rrc_proto.h" /* from OAI */ #include "pdcp.h" +#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #define TODO do { \ printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ @@ -43,6 +49,7 @@ static uint64_t pdcp_optmask; /* rlc_data_req queue - begin */ /****************************************************************************/ + #include /* NR PDCP and RLC both use "big locks". In some cases a thread may do @@ -92,6 +99,7 @@ static void *rlc_data_req_thread(void *_) { int i; + pthread_setname_np(pthread_self(), "RLC queue"); while (1) { if (pthread_mutex_lock(&q.m) != 0) abort(); while (q.length == 0) @@ -203,6 +211,7 @@ static void *enb_tun_read_thread(void *_) protocol_ctxt_t ctxt; int rb_id = 1; + pthread_setname_np( pthread_self(),"enb_tun_read"); while (1) { len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD); @@ -211,7 +220,7 @@ static void *enb_tun_read_thread(void *_) exit(1); } -printf("\n\n\n########## nas_sock_fd read returns len %d\n", len); + LOG_D(PDCP, "%s(): nas_sock_fd read returns len %d\n", __func__, len); nr_pdcp_manager_lock(nr_pdcp_ue_manager); rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager); @@ -247,7 +256,7 @@ static void *ue_tun_read_thread(void *_) protocol_ctxt_t ctxt; int rb_id = 1; - + pthread_setname_np( pthread_self(),"ue_tun_read"); while (1) { len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD); if (len == -1) { @@ -255,7 +264,7 @@ static void *ue_tun_read_thread(void *_) exit(1); } -printf("\n\n\n########## nas_sock_fd read returns len %d\n", len); + LOG_D(PDCP, "%s(): nas_sock_fd read returns len %d\n", __func__, len); nr_pdcp_manager_lock(nr_pdcp_ue_manager); rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager); @@ -368,7 +377,7 @@ uint64_t pdcp_module_init(uint64_t _pdcp_optmask) nas_getparams(); if(UE_NAS_USE_TUN) { - int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1; netlink_init_tun("ue",num_if); //Add --nr-ip-over-lte option check for next line if (IS_SOFTMODEM_NOS1) @@ -404,7 +413,6 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, len = write(nas_sock_fd[0], buf, size); if (len != size) { LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); } } else{ @@ -424,7 +432,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, size + GTPU_HEADER_OVERHEAD_MAX); AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf, size); - message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ); + message_p = itti_alloc_new_message(TASK_PDCP_ENB, 0, GTPV1U_ENB_TUNNEL_DATA_REQ); AssertFatal(message_p != NULL, "OUT OF MEMORY"); GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = size; @@ -589,8 +597,17 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) nr_pdcp_ue_t *ue; int drb_id = s->drb_Identity; + int t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); + int sn_size_ul = decode_sn_size_ul(*s->pdcp_Config->drb->pdcp_SN_SizeUL); + int sn_size_dl = decode_sn_size_dl(*s->pdcp_Config->drb->pdcp_SN_SizeDL); + int discard_timer = decode_discard_timer(*s->pdcp_Config->drb->discardTimer); -printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id); + /* TODO(?): accept different UL and DL SN sizes? */ + if (sn_size_ul != sn_size_dl) { + LOG_E(PDCP, "%s:%d:%s: fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", + __FILE__, __LINE__, __FUNCTION__, sn_size_ul, sn_size_dl); + exit(1); + } if (drb_id != 1) { LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n", @@ -604,11 +621,11 @@ printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id); LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue); + pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue, + sn_size_dl, t_reordering, discard_timer); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); - LOG_D(PDCP, "%s:%d:%s: added drb %d to ue %d\n", - __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -629,6 +646,7 @@ static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Co __FILE__, __LINE__, __FUNCTION__); exit(1); } + LOG_I(PDCP, "%s:%s:%d: added DRB for UE RNTI %x\n", __FILE__, __FUNCTION__, __LINE__, rnti); } boolean_t nr_rrc_pdcp_config_asn1_req( @@ -675,7 +693,6 @@ boolean_t nr_rrc_pdcp_config_asn1_req( if (drb2add_list != NULL) { for (i = 0; i < drb2add_list->list.count; i++) { - LOG_I(PDCP, "Before calling add_drb \n"); add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config); } } @@ -710,7 +727,7 @@ boolean_t rrc_pdcp_config_asn1_req( return 0; } -void nr_DRB_preconfiguration(void) +void nr_DRB_preconfiguration(uint16_t crnti) { NR_RadioBearerConfig_t *rbconfig = NULL; @@ -762,67 +779,19 @@ void nr_DRB_preconfiguration(void) xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); - NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); - - RLC_BearerConfig->logicalChannelIdentity = 4; - RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); - RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; - - RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1; - RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC)); - *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true; - RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); - - // RLC UM Bi-directional Bearer configuration - RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional; - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional)); - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; - - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; - - // RLC AM Bearer configuration - /*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; - RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am)); - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32; - - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;*/ - - RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters)); - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedServingCells = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup)); - *RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL; + nr_rlc_bearer_init(RLC_BearerConfig); + nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional); + nr_rlc_bearer_init_ul_spec(RLC_BearerConfig->mac_LogicalChannelConfig); Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list)); ASN_SEQUENCE_ADD(&Rlc_Bearer_ToAdd_list->list, RLC_BearerConfig); if (ENB_NAS_USE_TUN){ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, crnti, 0, 0, 0); } else{ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, crnti, 0, 0,0); } nr_rrc_pdcp_config_asn1_req( @@ -844,6 +813,9 @@ void nr_DRB_preconfiguration(void) rbconfig->drb_ToReleaseList, (LTE_PMCH_InfoList_r9_t *) NULL, Rlc_Bearer_ToAdd_list); + + LOG_D(PDCP, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %x\n", __FUNCTION__, __LINE__, ctxt.rnti); + } uint64_t get_pdcp_optmask(void) @@ -863,10 +835,45 @@ boolean_t pdcp_remove_UE( return 1; } -void pdcp_config_set_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_pP, rb_id_t rb_id, - uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP) +void pdcp_config_set_security( + const protocol_ctxt_t* const ctxt_pP, + pdcp_t *const pdcp_pP, + const rb_id_t rb_id, + const uint16_t lc_idP, + const uint8_t security_modeP, + uint8_t *const kRRCenc_pP, + uint8_t *const kRRCint_pP, + uint8_t *const kUPenc_pP) { - TODO; + DevAssert(pdcp_pP != NULL); + + if ((security_modeP >= 0) && (security_modeP <= 0x77)) { + pdcp_pP->cipheringAlgorithm = security_modeP & 0x0f; + pdcp_pP->integrityProtAlgorithm = (security_modeP>>4) & 0xf; + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_SET_SECURITY_MODE: cipheringAlgorithm %d integrityProtAlgorithm %d\n", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), + pdcp_pP->cipheringAlgorithm, + pdcp_pP->integrityProtAlgorithm); + pdcp_pP->kRRCenc = kRRCenc_pP; + pdcp_pP->kRRCint = kRRCint_pP; + pdcp_pP->kUPenc = kUPenc_pP; + /* Activate security */ + pdcp_pP->security_activated = 1; + MSC_LOG_EVENT( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + "0 Set security ciph %X integ %x UE %"PRIx16" ", + pdcp_pP->cipheringAlgorithm, + pdcp_pP->integrityProtAlgorithm, + ctxt_pP->rnti); + } else { + MSC_LOG_EVENT( + (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, + "0 Set security failed UE %"PRIx16" ", + ctxt_pP->rnti); + LOG_E(PDCP,PROTOCOL_PDCP_CTXT_FMT" bad security mode %d", + PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), + security_modeP); + } } static boolean_t pdcp_data_req_drb( diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 78a49e4604..1d4efc1e26 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -922,6 +922,7 @@ static missing_data_t next_missing(nr_rlc_entity_am_t *entity, */ ret.sn_start = entity->rx_next; ret.so_start = 0; + ret.next = cur; goto set_end_different_sdu; } } @@ -1284,7 +1285,7 @@ static int missing_size(nr_rlc_entity_am_t *entity, missing_data_t *m, 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; + sn_count = m->sn_end - m->sn_start + 1; if (sn_count < 0) sn_count += entity->sn_modulus; @@ -1580,7 +1581,7 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity, } if (entity->tx_size + size > entity->tx_maxsize) { - LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + LOG_E(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", __FILE__, __LINE__, __FUNCTION__); return; } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 5048dd245e..9c139624eb 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -27,6 +27,7 @@ #include "asn1_utils.h" #include "nr_rlc_ue_manager.h" #include "nr_rlc_entity.h" +#include "nr_rlc_oai_api.h" #include "NR_RLC-BearerConfig.h" #include "NR_DRB-ToAddMod.h" #include "NR_DRB-ToAddModList.h" @@ -44,6 +45,76 @@ static uint64_t nr_rlc_current_time; static int nr_rlc_current_time_last_frame; static int nr_rlc_current_time_last_subframe; +void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig){ + + + RLC_BearerConfig->servedRadioBearer = calloc(1, sizeof(*RLC_BearerConfig->servedRadioBearer)); + RLC_BearerConfig->reestablishRLC = calloc(1, sizeof(*RLC_BearerConfig->reestablishRLC)); + RLC_BearerConfig->rlc_Config = calloc(1, sizeof(*RLC_BearerConfig->rlc_Config)); + RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1, sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); + + RLC_BearerConfig->logicalChannelIdentity = 4; + RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; + RLC_BearerConfig->servedRadioBearer->choice.drb_Identity = 1; + *RLC_BearerConfig->reestablishRLC = NR_RLC_BearerConfig__reestablishRLC_true; + +} + +void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig){ + + mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters)); + mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1; + mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + mac_LogicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + mac_LogicalChannelConfig->ul_SpecificParameters->allowedServingCells = NULL; + mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL; + mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL; + mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL; + + mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup)); + *mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1; + mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL; + mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false; + mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false; + mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL; + +} + +void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr){ + + switch (rlc_config_pr){ + case NR_RLC_Config_PR_um_Bi_Directional: + // RLC UM Bi-directional Bearer configuration + rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional)); + rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); + *rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); + *rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; + break; + case NR_RLC_Config_PR_am: + // RLC AM Bearer configuration + rlc_Config->choice.am = calloc(1, sizeof(*rlc_Config->choice.am)); + rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); + *rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; + rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; + rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64; + rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500; + rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32; + rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); + *rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; + rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; + rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15; + break; + default: + LOG_E (RLC, "Error in %s: RLC config type %d is not handled\n", __FUNCTION__, rlc_config_pr); + break; + } + + rlc_Config->present = rlc_config_pr; + +} + void mac_rlc_data_ind ( const module_id_t module_idP, const rnti_t rntiP, @@ -179,6 +250,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( + buf_stat.retx_size + buf_stat.tx_size; } else { + LOG_W(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); ret.bytes_in_buffer = 0; } @@ -586,8 +658,7 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) 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); + LOG_W(RLC, "%s:%d:%s: SRB %d already exists for UE with RNTI %x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); } else { /* hack: hardcode values for NR */ t_poll_retransmit = 45; @@ -597,8 +668,8 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) poll_byte = -1; max_retx_threshold = 8; sn_field_length = 12; - nr_rlc_am = new_nr_rlc_entity_am(100000, - 100000, + nr_rlc_am = new_nr_rlc_entity_am(10000000, + 10000000, deliver_sdu, ue, successful_delivery, ue, max_retx_reached, ue, @@ -678,11 +749,10 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ 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); + LOG_W(RLC, "%s:%d:%s: DRB %d already exists for UE with RNTI %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - nr_rlc_am = new_nr_rlc_entity_am(100000, - 100000, + nr_rlc_am = new_nr_rlc_entity_am(10000000, + 10000000, deliver_sdu, ue, successful_delivery, ue, max_retx_reached, ue, @@ -692,8 +762,7 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ 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); + LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } @@ -752,18 +821,16 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ 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); + LOG_W(RLC, "DEBUG add_drb_um %s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - nr_rlc_um = new_nr_rlc_entity_um(1000000, - 1000000, + nr_rlc_um = new_nr_rlc_entity_um(100000000, + 100000000, 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); + LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } nr_rlc_manager_unlock(nr_rlc_ue_manager); } @@ -782,6 +849,7 @@ static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerCon __FILE__, __LINE__, __FUNCTION__); exit(1); } + LOG_I(RLC, "%s:%s:%d: added DRB to UE with RNTI %x\n", __FILE__, __FUNCTION__, __LINE__, rnti); } /* Dummy function due to dependency from LTE libraries */ @@ -809,7 +877,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt 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__, + LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %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); @@ -869,7 +937,7 @@ rlc_op_status_t rrc_rlc_config_req ( 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); + LOG_D(RLC, "%s:%d:%s: remove rb %ld (is_srb %d) for UE RNTI %x\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) { @@ -917,6 +985,19 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) void nr_rlc_tick(int frame, int subframe) { if (frame != nr_rlc_current_time_last_frame || - subframe != nr_rlc_current_time_last_subframe) + subframe != nr_rlc_current_time_last_subframe) { + nr_rlc_current_time_last_frame = frame; + nr_rlc_current_time_last_subframe = subframe; nr_rlc_current_time++; + } +} + +/* This is a hack, to compile the gNB. + * TODO: remove it. The solution is to cleanup cmake_targets/CMakeLists.txt + */ +void rlc_tick(int a, int b) +{ + LOG_E(RLC, "%s:%d:%s: this code should not be reached\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); } diff --git a/common/utils/itti_analyzer/libparser/union_type.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h similarity index 58% rename from common/utils/itti_analyzer/libparser/union_type.h rename to openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index ed2dca73ba..26dee0590b 100644 --- a/common/utils/itti_analyzer/libparser/union_type.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -19,21 +19,31 @@ * contact@openairinterface.org */ -#include "types.h" +/*! \file nr_rlc_oai_api.h + * \brief Header file for nr_rlc_oai_api + * \author Guido Casati + * \date 2020 + * \email: guido.casati@iis.fraunhofe.de + * \version 1.0 + * @ingroup _rlc -#ifndef UNION_TYPE_H_ -#define UNION_TYPE_H_ + */ -int union_msg_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); +#include "NR_RLC-BearerConfig.h" +#include "NR_RLC-Config.h" +#include "NR_LogicalChannelIdentity.h" +#include "NR_RadioBearerConfig.h" +#include "NR_CellGroupConfig.h" +#include "openair2/RRC/NR/nr_rrc_proto.h" -int union_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); +/* from OAI */ +#include "pdcp.h" -int union_type_file_print(types_t *type, int indent, FILE *file); +struct NR_RLC_Config; +struct NR_LogicalChannelConfig; -int union_type_hr_display(types_t *type, int indent); +void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig); -#endif /* UNION_TYPE_H_ */ +void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr); + +void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); \ No newline at end of file diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c index d4db8d8484..8c46628333 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c @@ -85,7 +85,7 @@ nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int rnti) 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); + LOG_D(RLC, "%s:%d:%s: new UE with RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, rnti); m->ue_count++; m->ue_list = realloc(m->ue_list, sizeof(nr_rlc_ue_t *) * m->ue_count); diff --git a/openair2/LAYER2/nr_rlc/tests/run_tests.sh b/openair2/LAYER2/nr_rlc/tests/run_tests.sh index ac22516064..bf1b343d7e 100755 --- a/openair2/LAYER2/nr_rlc/tests/run_tests.sh +++ b/openair2/LAYER2/nr_rlc/tests/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_count=13 +test_count=14 for i in `seq $test_count` do diff --git a/openair2/LAYER2/nr_rlc/tests/test14.h b/openair2/LAYER2/nr_rlc/tests/test14.h new file mode 100644 index 0000000000..9eb472b270 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test14.h @@ -0,0 +1,46 @@ +/* + * am test (SN field size 18): + * test status reporting with missing packet + * at time 1, UE receives an SDU of 50 bytes + * at time 2, UE receives an SDU of 50 bytes + * at time 3, UE receives an SDU of 50 bytes + * at time 4, UE receives an SDU of 50 bytes + * transmission fails for first SDU, okay for the others + * then some time with transmission failing + * then at time 49, UE receives an SDU, transmission okay + * then at time 50, transmission failing again (we had a bug triggered by this) + * finally at time 55, transmission okay again to clear buffers + */ + +TIME, 1, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + GNB_RECV_FAILS, 1, + GNB_PDU_SIZE, 80, + UE_PDU_SIZE, 80, + UE_SDU, 0, 50, +TIME, 2, + GNB_RECV_FAILS, 0, + UE_SDU, 1, 50, +TIME, 3, + GNB_BUFFER_STATUS, + UE_SDU, 2, 50, +TIME, 4, + GNB_BUFFER_STATUS, + UE_SDU, 3, 50, +TIME, 5, + GNB_BUFFER_STATUS, + GNB_RECV_FAILS, 1, +TIME, 6, + GNB_BUFFER_STATUS, + UE_BUFFER_STATUS, +TIME, 49, + GNB_RECV_FAILS, 0, + UE_SDU, 4, 50, +TIME, 50, + GNB_RECV_FAILS, 1, + GNB_BUFFER_STATUS, + UE_BUFFER_STATUS, +TIME, 55, + GNB_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz new file mode 100644 index 0000000000..7ab2fc3431 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/TODO b/openair2/LAYER2/rlc_v2/TODO index 0778d4320b..e93ad7e8b9 100644 --- a/openair2/LAYER2/rlc_v2/TODO +++ b/openair2/LAYER2/rlc_v2/TODO @@ -13,6 +13,3 @@ RLC AM - 36.322 5.1.3.2.3 Actions when a RLC data PDU is placed in the reception buffer [...] and in-sequence byte segments of the AMD PDU with SN = VR(R) [...] - -- use SOstart/SOend in NACK reporting, do not NACK full PDU if - parts of it have been received diff --git a/openair2/LAYER2/rlc_v2/rlc_entity_am.c b/openair2/LAYER2/rlc_v2/rlc_entity_am.c index b4f3d2f47c..710f22855e 100644 --- a/openair2/LAYER2/rlc_v2/rlc_entity_am.c +++ b/openair2/LAYER2/rlc_v2/rlc_entity_am.c @@ -898,6 +898,64 @@ static tx_pdu_size_t compute_new_pdu_size(rlc_entity_am_t *entity, int maxsize) return ret; } +/* return number of missing parts of a sn + * if everything is missing (nothing received), return 0 + */ +static int count_nack_missing_parts(rlc_entity_am_t *entity, int sn) +{ + rlc_rx_pdu_segment_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + int count; + + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + /* nothing received, everything is missing, return 0 */ + if (l == NULL) + return 0; + + last_byte = -1; + count = 0; + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + /* missing part detected */ + count++; + if (l->is_last) + /* end of PDU reached - no more missing part to add */ + return count; + new_last_byte = l->so + l->size - l->data_offset - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + /* at this point: end of PDU not received, one more missing part */ + count++; + + return count; +} + +/* return size of nack reporting for sn, in bits */ +static int segment_nack_size(rlc_entity_am_t *entity, int sn) +{ + /* nack + e1 + e2 = 12 bits + * SOstart + SOend = 30 bits + */ + int count; + + count = count_nack_missing_parts(entity, sn); + + /* count_nack_missing_parts returns 0 when everything is missing + * in which case we don't have SOstart/SOend, so only 12 bits + */ + if (count == 0) + return 12; + + return count * (12 + 30); +} + static int status_size(rlc_entity_am_t *entity, int maxsize) { /* let's count bits */ @@ -912,11 +970,16 @@ static int status_size(rlc_entity_am_t *entity, int maxsize) return 0; } - /* each NACK adds 12 bits */ + /* add size of NACKs */ sn = entity->vr_r; - while (bits + 12 <= maxsize && sn_compare_rx(entity, sn, entity->vr_ms) < 0) { - if (!(rlc_am_segment_full(entity, sn))) - bits += 12; + while (sn_compare_rx(entity, sn, entity->vr_ms) < 0) { + if (!(rlc_am_segment_full(entity, sn))) { + int nack_size = segment_nack_size(entity, sn); + /* stop there if not enough room */ + if (bits + nack_size > maxsize) + break; + bits += nack_size; + } sn = (sn + 1) % 1024; } @@ -929,7 +992,8 @@ static int generate_status(rlc_entity_am_t *entity, char *buffer, int size) int bits = 15; /* minimum size is 15 (header+ack_sn+e1) */ int sn; rlc_pdu_encoder_t encoder; - int has_nack = 0; + rlc_pdu_encoder_t encoder_ack; + rlc_pdu_encoder_t previous_e1; int ack; rlc_pdu_encoder_init(&encoder, buffer, size); @@ -947,24 +1011,68 @@ static int generate_status(rlc_entity_am_t *entity, char *buffer, int size) rlc_pdu_encoder_put_bits(&encoder, 0, 3); /* CPT */ /* reserve room for ACK (it will be set after putting the NACKs) */ + encoder_ack = encoder; rlc_pdu_encoder_put_bits(&encoder, 0, 10); + /* put 0 for e1, will be set to 1 later in the code if needed */ + previous_e1 = encoder; + rlc_pdu_encoder_put_bits(&encoder, 0, 1); /* at this point, ACK is VR(R) */ ack = entity->vr_r; - /* each NACK adds 12 bits */ sn = entity->vr_r; - while (bits + 12 <= size && sn_compare_rx(entity, sn, entity->vr_ms) < 0) { + while (sn_compare_rx(entity, sn, entity->vr_ms) < 0) { if (!(rlc_am_segment_full(entity, sn))) { - /* put previous e1 (is 1) */ - rlc_pdu_encoder_put_bits(&encoder, 1, 1); - /* if previous was NACK, put previous e2 (0, we don't do 'so' thing) */ - if (has_nack) - rlc_pdu_encoder_put_bits(&encoder, 0, 1); - /* put NACKed sn */ - rlc_pdu_encoder_put_bits(&encoder, sn, 10); - has_nack = 1; - bits += 12; + rlc_rx_pdu_segment_t *l; + int i; + int count = count_nack_missing_parts(entity, sn); + int nack_bits = count == 0 ? 12 : count * (12 + 30); + int last_byte; + int new_last_byte; + int so_start; + int so_end; + /* if not enough room, stop putting NACKs */ + if (bits + nack_bits > size) + break; + /* set previous e1 to 1 */ + rlc_pdu_encoder_put_bits(&previous_e1, 1, 1); + + if (count == 0) { + /* simply NACK, no SOstart/SOend */ + rlc_pdu_encoder_put_bits(&encoder, sn, 10); /* nack */ + previous_e1 = encoder; + rlc_pdu_encoder_put_bits(&encoder, 0, 2); /* e1, e2 */ + } else { + /* count is not 0, so we have 'count' NACK+e1+e2+SOstart+SOend */ + l = entity->rx_list; + last_byte = -1; + while (l->sn != sn) l = l->next; + for (i = 0; i < count; i++) { + rlc_pdu_encoder_put_bits(&encoder, sn, 10); /* nack */ + previous_e1 = encoder; + /* all NACKs but the last have a following NACK, set e1 for them */ + rlc_pdu_encoder_put_bits(&encoder, i != count - 1, 1); /* e1 */ + rlc_pdu_encoder_put_bits(&encoder, 1, 1); /* e2 */ + /* look for the next segment with missing data before it */ + while (l != NULL && l->sn == sn && !(l->so > last_byte + 1)) { + new_last_byte = l->so + l->size - l->data_offset - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + so_start = last_byte + 1; + if (l == NULL) + so_end = 0x7fff; + else + so_end = l->so - 1; + rlc_pdu_encoder_put_bits(&encoder, so_start, 15); + rlc_pdu_encoder_put_bits(&encoder, so_end, 15); + if (l != NULL) + last_byte = l->so + l->size - l->data_offset - 1; + } + } + + bits += nack_bits; } else { /* this sn is full and we put all NACKs before it, use it for ACK */ ack = (sn + 1) % 1024; @@ -972,24 +1080,10 @@ static int generate_status(rlc_entity_am_t *entity, char *buffer, int size) sn = (sn + 1) % 1024; } - /* go to highest full sn+1 for ACK, VR(MS) is the limit */ - while (sn_compare_rx(entity, sn, entity->vr_ms) < 0 && - rlc_am_segment_full(entity, sn)) { - ack = (sn + 1) % 1024; - sn = (sn + 1) % 1024; - } - - /* at this point, if last put was NACK then put 2 bits else put 1 bit */ - if (has_nack) - rlc_pdu_encoder_put_bits(&encoder, 0, 2); - else - rlc_pdu_encoder_put_bits(&encoder, 0, 1); - rlc_pdu_encoder_align(&encoder); /* let's put the ACK */ - buffer[0] |= ack >> 6; - buffer[1] |= (ack & 0x3f) << 2; + rlc_pdu_encoder_put_bits(&encoder_ack, ack, 10); /* reset the trigger */ entity->status_triggered = 0; diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c index bd3eebe635..919d577a18 100644 --- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c +++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c @@ -177,14 +177,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind( mac_rlc_status_resp_t ret; rlc_entity_t *rb; - /* TODO: handle time a bit more properly */ - if (rlc_current_time_last_frame != frameP || - rlc_current_time_last_subframe != subframeP) { - rlc_current_time++; - rlc_current_time_last_frame = frameP; - rlc_current_time_last_subframe = subframeP; - } - rlc_manager_lock(rlc_ue_manager); ue = rlc_manager_get_ue(rlc_ue_manager, rntiP); @@ -244,14 +236,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( exit(1); } - /* TODO: handle time a bit more properly */ - if (rlc_current_time_last_frame != frameP || - rlc_current_time_last_subframe != subframeP) { - rlc_current_time++; - rlc_current_time_last_frame = frameP; - rlc_current_time_last_subframe = subframeP; - } - rlc_manager_lock(rlc_ue_manager); ue = rlc_manager_get_ue(rlc_ue_manager, rntiP); @@ -443,7 +427,7 @@ rb_found: "Can't be CU, bad node type %d\n", type); if (NODE_IS_DU(type) && is_srb == 1) { - MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, F1AP_UL_RRC_MESSAGE); + MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, 0, F1AP_UL_RRC_MESSAGE); F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti; F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id; F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf; @@ -506,7 +490,7 @@ rb_found: if (!is_enb) return; - msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); + msg = itti_alloc_new_message(TASK_RLC_ENB, 0, 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; @@ -559,7 +543,7 @@ rb_found: if (!is_enb) return; - msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); + msg = itti_alloc_new_message(TASK_RLC_ENB, 0, 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; @@ -658,8 +642,7 @@ static void add_srb(int rnti, int module_id, struct LTE_SRB_ToAddMod *s) poll_pdu, poll_byte, max_retx_threshold); rlc_ue_add_srb_rlc_entity(ue, srb_id, rlc_am); - LOG_D(RLC, "%s:%d:%s: added srb %d to ue %d\n", - __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); + LOG_D(RLC, "%s:%d:%s: added SRB %d to UE RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); } rlc_manager_unlock(rlc_ue_manager); } @@ -736,8 +719,7 @@ static void add_drb_am(int rnti, int module_id, struct LTE_DRB_ToAddMod *s) poll_pdu, poll_byte, max_retx_threshold); rlc_ue_add_drb_rlc_entity(ue, drb_id, rlc_am); - LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", - __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_D(RLC, "%s:%d:%s: added DRB %d to UE RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } rlc_manager_unlock(rlc_ue_manager); } @@ -807,8 +789,7 @@ static void add_drb_um(int rnti, int module_id, struct LTE_DRB_ToAddMod *s) sn_field_length); rlc_ue_add_drb_rlc_entity(ue, drb_id, rlc_um); - LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", - __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + LOG_D(RLC, "%s:%d:%s: added DRB %d to UE RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } rlc_manager_unlock(rlc_ue_manager); } @@ -853,7 +834,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP if (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__, + LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %ld %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); @@ -925,8 +906,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP ); rlc_ue_add_drb_rlc_entity(ue, drb_id, rlc_um); - LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", - __FILE__, __LINE__, __FUNCTION__, (int)drb_id, mbms_rnti); + LOG_D(RLC, "%s:%d:%s: added DRB %d to UE RNTI %x\n", __FILE__, __LINE__, __FUNCTION__, (int)drb_id, mbms_rnti); } rlc_manager_unlock(rlc_ue_manager); @@ -1028,3 +1008,27 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } + +void rlc_tick(int frame, int subframe) +{ + int expected_next_frame; + int expected_next_subframe; + + if (frame != rlc_current_time_last_frame || + subframe != rlc_current_time_last_subframe) { + /* warn if discontinuity in ticks */ + expected_next_subframe = (rlc_current_time_last_subframe + 1) % 10; + if (expected_next_subframe == 0) + expected_next_frame = (rlc_current_time_last_frame + 1) % 1024; + else + expected_next_frame = rlc_current_time_last_frame; + if (expected_next_frame != frame || expected_next_subframe != subframe) + LOG_W(RLC, "rlc_tick: discontinuity (expected %d.%d, got %d.%d)\n", + expected_next_frame, expected_next_subframe, + frame, subframe); + + rlc_current_time++; + rlc_current_time_last_frame = frame; + rlc_current_time_last_subframe = subframe; + } +} diff --git a/openair2/LAYER2/rlc_v2/rlc_pdu.c b/openair2/LAYER2/rlc_v2/rlc_pdu.c index c55e2d9c3c..dc8fc8b094 100644 --- a/openair2/LAYER2/rlc_v2/rlc_pdu.c +++ b/openair2/LAYER2/rlc_v2/rlc_pdu.c @@ -233,9 +233,10 @@ static void put_bit(rlc_pdu_encoder_t *encoder, int bit) exit(1); } - encoder->buffer[encoder->byte] <<= 1; if (bit) - encoder->buffer[encoder->byte] |= 1; + encoder->buffer[encoder->byte] |= 1 << (7 - encoder->bit); + else + encoder->buffer[encoder->byte] &= ~(1 << (7 - encoder->bit)); encoder->bit++; if (encoder->bit == 8) { diff --git a/openair2/LAYER2/rlc_v2/tests/run_tests.sh b/openair2/LAYER2/rlc_v2/tests/run_tests.sh index 72feff0036..f3776157a3 100755 --- a/openair2/LAYER2/rlc_v2/tests/run_tests.sh +++ b/openair2/LAYER2/rlc_v2/tests/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_count=45 +test_count=49 for i in `seq $test_count` do diff --git a/openair2/LAYER2/rlc_v2/tests/test11.txt.gz b/openair2/LAYER2/rlc_v2/tests/test11.txt.gz index ea435a6660..160916bb36 100644 Binary files a/openair2/LAYER2/rlc_v2/tests/test11.txt.gz and b/openair2/LAYER2/rlc_v2/tests/test11.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test12.txt.gz b/openair2/LAYER2/rlc_v2/tests/test12.txt.gz index 988d7ae644..a416cfdd2e 100644 Binary files a/openair2/LAYER2/rlc_v2/tests/test12.txt.gz and b/openair2/LAYER2/rlc_v2/tests/test12.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test46.h b/openair2/LAYER2/rlc_v2/tests/test46.h new file mode 100644 index 0000000000..b58c9dce64 --- /dev/null +++ b/openair2/LAYER2/rlc_v2/tests/test46.h @@ -0,0 +1,49 @@ +/* + * rlc am test ack/nack reporting with segmented SDUs + * eNB sends SDU in big PDU, not received + * eNB retx with smaller PDUs, not received except a few + * after some time, RX works again, UE should NACK with SOstart/SOend + * + * this test was written because in the past we didn't generate NACKs with + * SOstart/SOend, potentially leading to infinite retransmissions, even with + * good radio conditions (well, there will be max ReTX reached at some point). + * The scenario is as follows: + * the eNB transmits many many PDUs segments and asks for status + * report at some point (but before sending all the segments). The UE then + * generates a (wrong) NACK without SOstart/SOend, and then the eNB has to + * resend everything from start (all bytes of the PDU have been NACKed because + * there is no SOstart/SOend). Then the eNB will again ask for status report + * before sending everything and the process repeats all over again. + */ +TIME, 1, + ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + UE_RECV_FAILS, 1, + ENB_RECV_FAILS, 1, + ENB_SDU, 0, 300, + ENB_PDU_SIZE, 500, + UE_PDU_SIZE, 1000, +TIME, 2, + ENB_PDU_SIZE, 7, +TIME, 50, + UE_RECV_FAILS, 0, +TIME, 51, + UE_RECV_FAILS, 1, +TIME, 60, + UE_RECV_FAILS, 0, +TIME, 61, + UE_RECV_FAILS, 1, +TIME, 70, + UE_RECV_FAILS, 0, +TIME, 71, + UE_RECV_FAILS, 1, +TIME, 80, + UE_RECV_FAILS, 0, +TIME, 81, + UE_RECV_FAILS, 1, +TIME, 140, + UE_RECV_FAILS, 0, + ENB_RECV_FAILS, 0, +TIME, 150, + ENB_PDU_SIZE, 200, +TIME, -1 diff --git a/openair2/LAYER2/rlc_v2/tests/test46.txt.gz b/openair2/LAYER2/rlc_v2/tests/test46.txt.gz new file mode 100644 index 0000000000..dd633ec032 Binary files /dev/null and b/openair2/LAYER2/rlc_v2/tests/test46.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test47.h b/openair2/LAYER2/rlc_v2/tests/test47.h new file mode 100644 index 0000000000..30cc6498da --- /dev/null +++ b/openair2/LAYER2/rlc_v2/tests/test47.h @@ -0,0 +1,27 @@ +/* + * am: test function segment_nack_size, case "if (count == 0) return 12;" + * The eNB sends 5 PDUs, only first and last received by the UE. Then we + * ask for the UE's buffer status to trigger the case. + */ +TIME, 1, + ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + ENB_RECV_FAILS, 1, + ENB_PDU_SIZE, 100, + UE_PDU_SIZE, 100, +TIME, 2, + ENB_SDU, 0, 10, +TIME, 3, + UE_RECV_FAILS, 1, + ENB_SDU, 1, 10, +TIME, 4, + ENB_SDU, 2, 10, +TIME, 5, + ENB_SDU, 3, 10, +TIME, 6, + UE_RECV_FAILS, 0, + ENB_RECV_FAILS, 0, + ENB_SDU, 4, 10, +TIME, 42, + UE_BUFFER_STATUS, +TIME, -1 diff --git a/openair2/LAYER2/rlc_v2/tests/test47.txt.gz b/openair2/LAYER2/rlc_v2/tests/test47.txt.gz new file mode 100644 index 0000000000..5404bd7936 Binary files /dev/null and b/openair2/LAYER2/rlc_v2/tests/test47.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test48.h b/openair2/LAYER2/rlc_v2/tests/test48.h new file mode 100644 index 0000000000..46c2c8ad33 --- /dev/null +++ b/openair2/LAYER2/rlc_v2/tests/test48.h @@ -0,0 +1,29 @@ +/* + * am: test case "if (bits + nack_size > maxsize)" in functions status_size + * and generate_status. + * The eNB sends 5 PDUs, only first and last received by the UE. Then we + * ask for the UE's buffer status to trigger the case. UE PDU size is + * limited to 6 to trigger the case. + */ +TIME, 1, + ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + ENB_RECV_FAILS, 1, + ENB_PDU_SIZE, 100, + UE_PDU_SIZE, 6, +TIME, 2, + ENB_SDU, 0, 10, +TIME, 3, + UE_RECV_FAILS, 1, + ENB_SDU, 1, 10, +TIME, 4, + ENB_SDU, 2, 10, +TIME, 5, + ENB_SDU, 3, 10, +TIME, 6, + UE_RECV_FAILS, 0, + ENB_RECV_FAILS, 0, + ENB_SDU, 4, 10, +TIME, 42, + UE_BUFFER_STATUS, +TIME, -1 diff --git a/openair2/LAYER2/rlc_v2/tests/test48.txt.gz b/openair2/LAYER2/rlc_v2/tests/test48.txt.gz new file mode 100644 index 0000000000..c1797b73bb Binary files /dev/null and b/openair2/LAYER2/rlc_v2/tests/test48.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test49.h b/openair2/LAYER2/rlc_v2/tests/test49.h new file mode 100644 index 0000000000..edeec27403 --- /dev/null +++ b/openair2/LAYER2/rlc_v2/tests/test49.h @@ -0,0 +1,27 @@ +/* + * rlc am test ack/nack reporting with segmented SDUs + * + * 5 SDUs put into 6 PDUs, all PDUs received expect the 3rd. Then + * retransmission happens with smaller PDU size. + */ +TIME, 1, + ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + UE_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, + ENB_SDU, 0, 60, + ENB_SDU, 1, 160, + ENB_SDU, 2, 130, + ENB_SDU, 3, 120, + ENB_SDU, 4, 100, + ENB_PDU_SIZE, 100, + UE_PDU_SIZE, 1000, +TIME, 3, + UE_RECV_FAILS, 1, +TIME, 4, + UE_RECV_FAILS, 0, +TIME, 7, + ENB_PDU_SIZE, 40, +TIME, 42, + UE_RECV_FAILS, 1, +TIME, 80, + UE_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/rlc_v2/tests/test49.txt.gz b/openair2/LAYER2/rlc_v2/tests/test49.txt.gz new file mode 100644 index 0000000000..752a1aedd5 Binary files /dev/null and b/openair2/LAYER2/rlc_v2/tests/test49.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test6.h b/openair2/LAYER2/rlc_v2/tests/test6.h index 2115c8a328..f778749729 100644 --- a/openair2/LAYER2/rlc_v2/tests/test6.h +++ b/openair2/LAYER2/rlc_v2/tests/test6.h @@ -5,9 +5,6 @@ * [1..600] is received but ACK/NACK not * eNB retx with still smaller PDUs [1..400] [401..600] [601..900] * all is received, ACKs/NACKs go through - * - * this test will fail if NACK mechanism uses SOstart/SOend - * (not implemented for the moment) */ TIME, 1, ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, diff --git a/openair2/LAYER2/rlc_v2/tests/test6.txt.gz b/openair2/LAYER2/rlc_v2/tests/test6.txt.gz index 54870821a6..345c149eec 100644 Binary files a/openair2/LAYER2/rlc_v2/tests/test6.txt.gz and b/openair2/LAYER2/rlc_v2/tests/test6.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test7.h b/openair2/LAYER2/rlc_v2/tests/test7.h index 081227a400..83e9083b10 100644 --- a/openair2/LAYER2/rlc_v2/tests/test7.h +++ b/openair2/LAYER2/rlc_v2/tests/test7.h @@ -6,9 +6,6 @@ * eNB retx with still smaller PDUs [1..400] [401..600] [601..900] * [401..600] received, ACK goes through * link clean, all goes through - * - * this test will fail if NACK mechanism uses SOstart/SOend - * (not implemented for the moment) */ TIME, 1, ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, diff --git a/openair2/LAYER2/rlc_v2/tests/test7.txt.gz b/openair2/LAYER2/rlc_v2/tests/test7.txt.gz index 9976a60507..48148755dc 100644 Binary files a/openair2/LAYER2/rlc_v2/tests/test7.txt.gz and b/openair2/LAYER2/rlc_v2/tests/test7.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/tests/test9.h b/openair2/LAYER2/rlc_v2/tests/test9.h index 88e23d94e9..2da9732012 100644 --- a/openair2/LAYER2/rlc_v2/tests/test9.h +++ b/openair2/LAYER2/rlc_v2/tests/test9.h @@ -11,9 +11,6 @@ * In the current RLC implementation, this is impossible. If we send [12..21] * it means [1..21] has been split and so we won't sent it later on. * Maybe with HARQ retransmissions in PHY/MAC in bad radio conditions? - * - * this test will fail if NACK mechanism uses SOstart/SOend - * (not implemented for the moment) */ TIME, 1, ENB_AM, 100000, 100000, 35, 0, 45, -1, -1, 4, diff --git a/openair2/LAYER2/rlc_v2/tests/test9.txt.gz b/openair2/LAYER2/rlc_v2/tests/test9.txt.gz index cc6d934e70..d3803062aa 100644 Binary files a/openair2/LAYER2/rlc_v2/tests/test9.txt.gz and b/openair2/LAYER2/rlc_v2/tests/test9.txt.gz differ diff --git a/openair2/M2AP/m2ap_MCE.c b/openair2/M2AP/m2ap_MCE.c index 096f3cabee..f163aa453a 100644 --- a/openair2/M2AP/m2ap_MCE.c +++ b/openair2/M2AP/m2ap_MCE.c @@ -105,7 +105,7 @@ void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_associa DevAssert(sctp_new_association_resp != NULL); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - LOG_W(M2AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + LOG_W(M2AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -233,7 +233,7 @@ int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p, sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG_MULTI_REQ); + message = itti_alloc_new_message (TASK_M2AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ); sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = mce_port_for_M2C; sctp_init->ppid = M2AP_SCTP_PPID; @@ -267,7 +267,7 @@ static void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_mce_data = NULL; DevAssert(instance_p != NULL); DevAssert(target_MCE_ip_address != NULL); - message = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI); + message = itti_alloc_new_message(TASK_M2AP_MCE, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI); sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; sctp_new_association_req->port = mce_port_for_M2C; sctp_new_association_req->ppid = M2AP_SCTP_PPID; @@ -312,7 +312,7 @@ void m2ap_MCE_handle_register_MCE(instance_t instance, DevCheck(new_instance->tac == m2ap_register_MCE->tac, new_instance->tac, m2ap_register_MCE->tac, 0); DevCheck(new_instance->mcc == m2ap_register_MCE->mcc, new_instance->mcc, m2ap_register_MCE->mcc, 0); DevCheck(new_instance->mnc == m2ap_register_MCE->mnc, new_instance->mnc, m2ap_register_MCE->mnc, 0); - M2AP_WARN("MCE[%d] already registered\n", instance); + M2AP_WARN("MCE[%ld] already registered\n", instance); } else { new_instance = calloc(1, sizeof(m2ap_MCE_instance_t)); DevAssert(new_instance != NULL); @@ -356,7 +356,7 @@ void m2ap_MCE_handle_register_MCE(instance_t instance, new_instance->mce_port_for_M2C = m2ap_register_MCE->mce_port_for_M2C; /* Add the new instance to the list of MCE (meaningfull in virtual mode) */ m2ap_MCE_insert_new_instance(new_instance); - M2AP_INFO("Registered new MCE[%d] and %s MCE id %u\n", + M2AP_INFO("Registered new MCE[%ld] and %s MCE id %u\n", instance, m2ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home", m2ap_register_MCE->MCE_id); @@ -367,7 +367,7 @@ void m2ap_MCE_handle_register_MCE(instance_t instance, return; } - M2AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n", + M2AP_INFO("MCE[%ld] MCE id %u acting as a listner (server)\n", instance, m2ap_register_MCE->MCE_id); } } @@ -394,7 +394,7 @@ void m2ap_MCE_handle_sctp_init_msg_multi_cnf( /* Trying to connect to the provided list of MCE ip address */ for (index = 0; index < instance->nb_m2; index++) { - M2AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n", + M2AP_INFO("MCE[%ld] MCE id %u acting as an initiator (client)\n", instance_id, instance->MCE_id); m2ap_MCE_register_MCE(instance, &instance->target_mce_m2_ip_address[index], @@ -507,7 +507,7 @@ void MCE_task_send_sctp_init_req(instance_t enb_id, m2ap_mce_sctp_req_t * m2ap_m LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n"); MessageDef *message_p = NULL; - message_p = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG); + message_p = itti_alloc_new_message (TASK_M2AP_MCE, 0, SCTP_INIT_MSG); // if( m2ap_mce_sctp_req == NULL ){ // message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER; @@ -558,7 +558,7 @@ void *m2ap_MCE_task(void *arg) { switch (ITTI_MSG_ID(received_msg)) { case MESSAGE_TEST: LOG_W(M2AP,"MCE Received MESSAGE_TEST Message\n"); - //MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_MCE, MESSAGE_TEST); + //MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_MCE, 0, MESSAGE_TEST); //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p); break; case TERMINATE_MESSAGE: @@ -567,29 +567,29 @@ void *m2ap_MCE_task(void *arg) { break; case M2AP_MCE_SCTP_REQ: - MCE_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MCE_task_send_sctp_init_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MCE_SCTP_REQ(received_msg)); break; case M2AP_SUBFRAME_PROCESS: - m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + m2ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); break; case M2AP_REGISTER_MCE_REQ: LOG_I(M2AP,"MCE Received M2AP_REGISTER_MCE_REQ Message\n"); - m2ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_MCE_handle_register_MCE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_REGISTER_MCE_REQ(received_msg)); break; case M2AP_SETUP_RESP: LOG_I(M2AP,"MCE Received M2AP_SETUP_RESP Message\n"); - MCE_send_M2_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MCE_send_M2_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_SETUP_RESP(received_msg)); break; case M2AP_SETUP_FAILURE: LOG_I(M2AP,"MCE Received M2AP_SETUP_FAILURE Message\n"); - MCE_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MCE_send_M2_SETUP_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_SETUP_FAILURE(received_msg)); break; @@ -644,41 +644,41 @@ void *m2ap_MCE_task(void *arg) { // case M2AP_HANDOVER_REQ: -// m2ap_MCE_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m2ap_MCE_handle_handover_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M2AP_HANDOVER_REQ(received_msg)); // break; // // case M2AP_HANDOVER_REQ_ACK: -// m2ap_MCE_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m2ap_MCE_handle_handover_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M2AP_HANDOVER_REQ_ACK(received_msg)); // break; // // case M2AP_UE_CONTEXT_RELEASE: -// m2ap_MCE_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m2ap_MCE_ue_context_release(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M2AP_UE_CONTEXT_RELEASE(received_msg)); // break; // case SCTP_INIT_MSG_MULTI_CNF: LOG_D(M2AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n"); - m2ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); break; case SCTP_NEW_ASSOCIATION_RESP: LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n"); - m2ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_MCE_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_NEW_ASSOCIATION_IND: LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n"); - m2ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_MCE_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind); break; case SCTP_DATA_IND: LOG_D(M2AP,"MCE Received SCTP_DATA_IND Message\n"); - m2ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_MCE_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; diff --git a/openair2/M2AP/m2ap_MCE_handler.c b/openair2/M2AP/m2ap_MCE_handler.c index 85e342f996..5a0e303218 100644 --- a/openair2/M2AP/m2ap_MCE_handler.c +++ b/openair2/M2AP/m2ap_MCE_handler.c @@ -113,7 +113,7 @@ int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre } /* Calling the right handler */ - LOG_I(M2AP, "Calling handler with instance %d\n",instance); + LOG_I(M2AP, "Calling handler with instance %ld\n",instance); ret = (*m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); diff --git a/openair2/M2AP/m2ap_MCE_interface_management.c b/openair2/M2AP/m2ap_MCE_interface_management.c index e162c9a5de..3b12f41cbe 100644 --- a/openair2/M2AP/m2ap_MCE_interface_management.c +++ b/openair2/M2AP/m2ap_MCE_interface_management.c @@ -179,7 +179,7 @@ int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance, int ENB_MBMS_M2AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SESSION_START_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE, 0,M2AP_MBMS_SESSION_START_RESP); //TODO LOG_D(M2AP, "M2AP: SessionStart-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -317,7 +317,7 @@ int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance, int ENB_MBMS_M2AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SESSION_STOP_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE, 0,M2AP_MBMS_SESSION_STOP_RESP); //TODO LOG_D(M2AP, "M2AP: SessionStop-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -616,7 +616,7 @@ int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance, //int ENB_MBMS_M2AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SCHEDULING_INFORMATION_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE, 0,M2AP_MBMS_SCHEDULING_INFORMATION_RESP); //TODO // LOG_D(M2AP, "M2AP: SessionStop-Resp: protocolIEs.list.count %d\n", // in->protocolIEs.list.count); @@ -720,7 +720,7 @@ int MCE_handle_M2_SETUP_REQUEST(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message(TASK_MCE_APP, M2AP_SETUP_REQ); + message_p = itti_alloc_new_message(TASK_MCE_APP, 0, M2AP_SETUP_REQ); /* assoc_id */ M2AP_SETUP_REQ(message_p).assoc_id = assoc_id; @@ -1193,7 +1193,7 @@ int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance, //M2AP_MCEConfigurationUpdateFailure_Ies_t *ie; - MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_FAILURE); + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_MCE, 0, M2AP_MCE_CONFIGURATION_UPDATE_FAILURE); LOG_D(M2AP, "M2AP: MCEConfigurationUpdate-Failure: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -1258,7 +1258,7 @@ int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_ACK); + message_p = itti_alloc_new_message (TASK_M2AP_MCE, 0, M2AP_MCE_CONFIGURATION_UPDATE_ACK); itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -1295,7 +1295,7 @@ int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_MCE, M2AP_MCE_CONFIGURATION_UPDATE_ACK); + message_p = itti_alloc_new_message (TASK_M2AP_MCE, 0, M2AP_MCE_CONFIGURATION_UPDATE_ACK); itti_send_msg_to_task(TASK_MCE_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -1399,7 +1399,7 @@ int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance, //int ENB_MBMS_M2AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE,M2AP_MBMS_SERVICE_COUNTING_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M2AP_MCE, 0,M2AP_MBMS_SERVICE_COUNTING_RESP); //TODO LOG_D(M2AP, "M2AP: MbmsServiceCounting-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); diff --git a/openair2/M2AP/m2ap_eNB.c b/openair2/M2AP/m2ap_eNB.c index 39c769a43d..c72eda7d8c 100644 --- a/openair2/M2AP/m2ap_eNB.c +++ b/openair2/M2AP/m2ap_eNB.c @@ -136,7 +136,7 @@ void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa //dump_trees_m2(); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -233,7 +233,7 @@ int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p, sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M2AP_ENB, SCTP_INIT_MSG_MULTI_REQ); + message = itti_alloc_new_message (TASK_M2AP_ENB, 0, SCTP_INIT_MSG_MULTI_REQ); sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = enb_port_for_M2C; sctp_init->ppid = M2AP_SCTP_PPID; @@ -267,7 +267,7 @@ static void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_enb_data = NULL; DevAssert(instance_p != NULL); DevAssert(target_eNB_ip_address != NULL); - message = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_NEW_ASSOCIATION_REQ_MULTI); + message = itti_alloc_new_message(TASK_M2AP_ENB, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI); sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; sctp_new_association_req->port = enb_port_for_M2C; sctp_new_association_req->ppid = M2AP_SCTP_PPID; @@ -319,7 +319,7 @@ void m2ap_eNB_handle_register_eNB(instance_t instance, DevCheck(new_instance->tac == m2ap_register_eNB->tac, new_instance->tac, m2ap_register_eNB->tac, 0); DevCheck(new_instance->mcc == m2ap_register_eNB->mcc, new_instance->mcc, m2ap_register_eNB->mcc, 0); DevCheck(new_instance->mnc == m2ap_register_eNB->mnc, new_instance->mnc, m2ap_register_eNB->mnc, 0); - M2AP_WARN("eNB[%d] already registered\n", instance); + M2AP_WARN("eNB[%ld] already registered\n", instance); } else { @@ -376,7 +376,7 @@ void m2ap_eNB_handle_register_eNB(instance_t instance, /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ m2ap_eNB_insert_new_instance(new_instance); - M2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n", + M2AP_INFO("Registered new eNB[%ld] and %s eNB id %u\n", instance, m2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", m2ap_register_eNB->eNB_id); @@ -387,7 +387,7 @@ void m2ap_eNB_handle_register_eNB(instance_t instance, return; } - M2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n", + M2AP_INFO("eNB[%ld] eNB id %u acting as a listner (server)\n", instance, m2ap_register_eNB->eNB_id); } } @@ -414,7 +414,7 @@ void m2ap_eNB_handle_sctp_init_msg_multi_cnf( /* Trying to connect to the provided list of eNB ip address */ for (index = 0; index < instance->nb_m2; index++) { - M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n", + M2AP_INFO("eNB[%ld] eNB id %u acting as an initiator (client)\n", instance_id, instance->eNB_id); m2ap_eNB_register_eNB(instance, &instance->target_mce_m2_ip_address[index], @@ -527,7 +527,7 @@ void m2ap_eNB_handle_sctp_init_msg_multi_cnf( // LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n"); // MessageDef *message_p = NULL; // -// message_p = itti_alloc_new_message (M2AP, SCTP_INIT_MSG); +// message_p = itti_alloc_new_message (M2AP, 0, SCTP_INIT_MSG); // message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER; // message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID; // message_p->ittiMsg.sctp_init.ipv4 = 1; @@ -561,7 +561,7 @@ void *m2ap_eNB_task(void *arg) { switch (ITTI_MSG_ID(received_msg)) { case MESSAGE_TEST: LOG_D(M2AP,"eNB Received MESSAGE_TEST Message %s\n",itti_get_task_name(ITTI_MSG_ORIGIN_ID(received_msg))); - //MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_ENB, MESSAGE_TEST); + //MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_ENB, 0, MESSAGE_TEST); //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p); break; case TERMINATE_MESSAGE: @@ -570,104 +570,104 @@ void *m2ap_eNB_task(void *arg) { break; case M2AP_SUBFRAME_PROCESS: - m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + m2ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); break; case M2AP_REGISTER_ENB_REQ: LOG_I(M2AP,"eNB Received M2AP_REGISTER_ENB_REQ Message\n"); - m2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_REGISTER_ENB_REQ(received_msg)); break; case M2AP_MBMS_SCHEDULING_INFORMATION_RESP: LOG_I(M2AP,"eNB M2AP_MBMS_SCHEDULING_INFORMATION_RESP Message\n"); - eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SCHEDULING_INFORMATION_RESP(received_msg)); break; case M2AP_MBMS_SESSION_START_RESP: LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_RESP Message\n"); - eNB_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SESSION_START_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SESSION_START_RESP(received_msg)); break; case M2AP_MBMS_SESSION_START_FAILURE: LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_FAILURE Message\n"); - eNB_send_MBMS_SESSION_START_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SESSION_START_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SESSION_START_FAILURE(received_msg)); break; case M2AP_MBMS_SESSION_STOP_RESP: LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_STOP_RESP Message\n"); - eNB_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SESSION_STOP_RESP(received_msg)); break; case M2AP_ENB_CONFIGURATION_UPDATE: LOG_I(M2AP,"eNB M2AP_ENB_CONFIGURATION_UPDATE Message\n"); - eNB_send_eNB_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_eNB_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_ENB_CONFIGURATION_UPDATE(received_msg)); break; case M2AP_MCE_CONFIGURATION_UPDATE_ACK: LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_ACK Message\n"); - //eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + //eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M2AP_MCE_CONFIGURATION_UPDATE_ACK(received_msg)); break; case M2AP_MCE_CONFIGURATION_UPDATE_FAILURE: LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_FAILURE Message\n"); - //(ITTI_MESSAGE_GET_INSTANCE(received_msg), + //(ITTI_MSG_DESTINATION_INSTANCE(received_msg), //&M2AP_MCE_CONFIGURATION_UPDATE_FAILURE(received_msg)); break; case M2AP_MBMS_SESSION_UPDATE_RESP: LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_RESP Message\n"); - eNB_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SESSION_UPDATE_RESP(received_msg)); break; case M2AP_MBMS_SESSION_UPDATE_FAILURE: LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_FAILURE Message\n"); - eNB_send_MBMS_SESSION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SESSION_UPDATE_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SESSION_UPDATE_FAILURE(received_msg)); break; case M2AP_MBMS_SERVICE_COUNTING_REPORT: LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_REPORT Message\n"); - eNB_send_MBMS_SERVICE_COUNTING_REPORT(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SERVICE_COUNTING_REPORT(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SERVICE_COUNTING_REPORT(received_msg)); break; case M2AP_MBMS_OVERLOAD_NOTIFICATION: LOG_I(M2AP,"eNB M2AP_MBMS_OVERLOAD_NOTIFICATION Message\n"); - eNB_send_MBMS_OVERLOAD_NOTIFICATION(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_OVERLOAD_NOTIFICATION(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_OVERLOAD_NOTIFICATION(received_msg)); break; case M2AP_MBMS_SERVICE_COUNTING_RESP: LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_RESP Message\n"); - eNB_send_MBMS_SERVICE_COUNTING_RESP(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SERVICE_COUNTING_RESP(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SERVICE_COUNTING_RESP(received_msg)); break; case M2AP_MBMS_SERVICE_COUNTING_FAILURE: LOG_I(M2AP,"eNB Message\n"); - eNB_send_MBMS_SERVICE_COUNTING_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + eNB_send_MBMS_SERVICE_COUNTING_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M2AP_MBMS_SERVICE_COUNTING_FAILURE(received_msg)); break; case SCTP_INIT_MSG_MULTI_CNF: LOG_I(M2AP,"eNB Received SCTP_INIT_MSG_MULTI_CNF Message\n"); - m2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); break; case SCTP_NEW_ASSOCIATION_RESP: LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION_RESP Message\n"); - m2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_NEW_ASSOCIATION_IND: LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION Message\n"); - m2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_eNB_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind); break; case SCTP_DATA_IND: LOG_I(M2AP,"eNB Received SCTP_DATA_IND Message\n"); - m2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m2ap_eNB_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; diff --git a/openair2/M2AP/m2ap_eNB_handler.c b/openair2/M2AP/m2ap_eNB_handler.c index fe0059f0a5..9abc337408 100644 --- a/openair2/M2AP/m2ap_eNB_handler.c +++ b/openair2/M2AP/m2ap_eNB_handler.c @@ -113,7 +113,7 @@ int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre } /* Calling the right handler */ - LOG_I(M2AP, "Calling handler with instance %d\n",instance); + LOG_I(M2AP, "Calling handler with instance %ld\n",instance); ret = (*m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu); diff --git a/openair2/M2AP/m2ap_eNB_interface_management.c b/openair2/M2AP/m2ap_eNB_interface_management.c index 9649d919c3..486e382e69 100644 --- a/openair2/M2AP/m2ap_eNB_interface_management.c +++ b/openair2/M2AP/m2ap_eNB_interface_management.c @@ -85,8 +85,8 @@ int eNB_handle_MBMS_SCHEDULING_INFORMATION(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SCHEDULING_INFORMATION); - //message_p2 = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SCHEDULING_INFORMATION); + message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MBMS_SCHEDULING_INFORMATION); + //message_p2 = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MBMS_SCHEDULING_INFORMATION); @@ -292,7 +292,7 @@ int eNB_handle_MBMS_SESSION_START_REQUEST(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_START_REQ); + message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MBMS_SESSION_START_REQ); itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -463,7 +463,7 @@ int eNB_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_STOP_REQ); + message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MBMS_SESSION_STOP_REQ); itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -749,8 +749,8 @@ int eNB_handle_M2_SETUP_RESPONSE(instance_t instance, //M2AP_Cells_to_be_Activated_List_Item_t *cell; int i,j; - MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_RESP); - //MessageDef *msg_p2 = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_RESP); + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_SETUP_RESP); + //MessageDef *msg_p2 = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_SETUP_RESP); LOG_D(M2AP, "M2AP: M2Setup-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -856,7 +856,7 @@ int eNB_handle_M2_SETUP_FAILURE(instance_t instance, M2AP_M2SetupFailure_Ies_t *ie; - MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_SETUP_FAILURE); + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_SETUP_FAILURE); LOG_D(M2AP, "M2AP: M2Setup-Failure: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -1062,7 +1062,7 @@ int eNB_handle_eNB_CONFIGURATION_UPDATE_FAILURE(instance_t instance, //M2AP_ENBConfigurationUpdateFailure_Ies_t *ie; - MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE); + MessageDef *msg_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE); LOG_D(M2AP, "M2AP: ENBConfigurationUpdate-Failure: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -1127,7 +1127,7 @@ int eNB_handle_eNB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_ENB_CONFIGURATION_UPDATE_ACK); + message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_ENB_CONFIGURATION_UPDATE_ACK); itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -1162,7 +1162,7 @@ int eNB_handle_MCE_CONFIGURATION_UPDATE(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MCE_CONFIGURATION_UPDATE); + message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MCE_CONFIGURATION_UPDATE); itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -1233,7 +1233,7 @@ int eNB_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, assoc_id, stream); } - message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SESSION_UPDATE_REQ); + message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MBMS_SESSION_UPDATE_REQ); itti_send_msg_to_task(TASK_ENB_APP, ENB_MODULE_ID_TO_INSTANCE(instance), message_p); @@ -1321,7 +1321,7 @@ int eNB_handle_MBMS_SERVICE_COUNTING_REQ(instance_t instance, - //message_p = itti_alloc_new_message (TASK_M2AP_ENB, M2AP_MBMS_SERVICE_COUNTING_REQ); + //message_p = itti_alloc_new_message (TASK_M2AP_ENB, 0, M2AP_MBMS_SERVICE_COUNTING_REQ); return 0; diff --git a/openair2/M2AP/m2ap_eNB_management_procedures.c b/openair2/M2AP/m2ap_eNB_management_procedures.c index b3ada92fa8..59d91afb74 100644 --- a/openair2/M2AP/m2ap_eNB_management_procedures.c +++ b/openair2/M2AP/m2ap_eNB_management_procedures.c @@ -116,7 +116,7 @@ void dump_trees_m2(void) m2ap_eNB_instance_t *zz; STAILQ_FOREACH(zz, &m2ap_eNB_internal_data.m2ap_eNB_instances_head, m2ap_eNB_entries) { -printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +printf("here comes the tree (instance %ld):\n---------------------------------------------\n", zz->instance); dump_tree_m2(zz->m2ap_enb_head.rbh_root); printf("---------------------------------------------\n"); } diff --git a/openair2/M2AP/m2ap_itti_messaging.c b/openair2/M2AP/m2ap_itti_messaging.c index b9cfd32901..e0dcc27175 100644 --- a/openair2/M2AP/m2ap_itti_messaging.c +++ b/openair2/M2AP/m2ap_itti_messaging.c @@ -36,7 +36,7 @@ void m2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_M2AP_ENB, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -56,7 +56,7 @@ void m2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t asso MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_M2AP_ENB, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; @@ -70,7 +70,7 @@ void m2ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_M2AP_MCE, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -88,7 +88,7 @@ void m2ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t asso MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_M2AP_MCE, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; diff --git a/openair2/MCE_APP/mce_app.c b/openair2/MCE_APP/mce_app.c index 817c863f7b..3572de215c 100644 --- a/openair2/MCE_APP/mce_app.c +++ b/openair2/MCE_APP/mce_app.c @@ -78,7 +78,7 @@ static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, u { // M3AP registration /* note: there is an implicit relationship between the data structure and the message name */ - msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_REGISTER_MCE_REQ); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M3AP_REGISTER_MCE_REQ); //RCconfig_S1(msg_p, mce_id); //if (mce_id == 0) @@ -92,7 +92,7 @@ static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, u //if (NODE_IS_DU(node_type)) { // F1AP registration // // configure F1AP here for F1C // LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); - // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); + // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, F1AP_SETUP_REQ); // RCconfig_DU_F1(msg_p, enb_id); // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); @@ -101,7 +101,7 @@ static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, u //} //else { // S1AP registration // /* note: there is an implicit relationship between the data structure and the message name */ - // msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); + // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, S1AP_REGISTER_ENB_REQ); // RCconfig_S1(msg_p, enb_id); // if (enb_id == 0) RCconfig_gtpu(); @@ -128,7 +128,7 @@ static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, u // // for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { // { -// msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); +// msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, X2AP_REGISTER_ENB_REQ); // RCconfig_X2(msg_p, mce_id); // itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); // register_mce_x2_pending++; @@ -148,7 +148,7 @@ static uint32_t MCE_app_register(ngran_node_t node_type,uint32_t mce_id_start, u // for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { // { // // LOG_W(MCE_APP,"Register commes inside ...\n"); -// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_REGISTER_MCE_REQ); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_REGISTER_MCE_REQ); // //RCconfig_M2_MCE(msg_p, mce_id); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); // // LOG_W(MCE_APP,"Register sent ...\n"); @@ -169,7 +169,7 @@ static uint32_t MCE_app_register_m3(uint32_t mce_id_start, uint32_t mce_id_end) for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { { // LOG_W(MCE_APP,"Register commes inside ...\n"); - msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_REGISTER_MCE_REQ); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M3AP_REGISTER_MCE_REQ); RCconfig_M3(msg_p, mce_id); itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); LOG_D(MCE_APP,"Register sent ...\n"); @@ -184,7 +184,7 @@ static uint32_t MCE_app_register_m3(uint32_t mce_id_start, uint32_t mce_id_end) //static uint32_t MCE_app_handle_m3ap_mbms_session_start_req(instance_t instance){ // //uint32_t mce_id=0; // // MessageDef *msg_p; -// // msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_START_RESP); +// // msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M3AP_MBMS_SESSION_START_RESP); // // itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // @@ -194,7 +194,7 @@ static uint32_t MCE_app_register_m3(uint32_t mce_id_start, uint32_t mce_id_end) static uint32_t MCE_app_handle_m3ap_mbms_session_stop_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_STOP_RESP); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M3AP_MBMS_SESSION_STOP_RESP); itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -203,7 +203,7 @@ static uint32_t MCE_app_handle_m3ap_mbms_session_stop_req(instance_t instance){ static uint32_t MCE_app_handle_m3ap_mbms_session_update_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_UPDATE_RESP); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M3AP_MBMS_SESSION_UPDATE_RESP); itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -216,7 +216,7 @@ static uint32_t MCE_app_handle_m2ap_setup_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_SETUP_RESP); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_SETUP_RESP); if(m2ap_setup_resp_local) memcpy(&M2AP_SETUP_RESP(msg_p),m2ap_setup_resp_local,sizeof(m2ap_setup_resp_t)); else @@ -230,7 +230,7 @@ static uint32_t MCE_app_handle_m2ap_setup_req(instance_t instance){ static uint32_t MCE_app_handle_m2ap_mbms_session_start_resp(instance_t instance){ MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MCE_APP, M3AP_MBMS_SESSION_START_RESP); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M3AP_MBMS_SESSION_START_RESP); itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; } @@ -243,7 +243,7 @@ static uint32_t MCE_app_send_m2ap_mbms_scheduling_information(instance_t instanc //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SCHEDULING_INFORMATION); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_MBMS_SCHEDULING_INFORMATION); if(m2ap_mbms_scheduling_information_local) memcpy(&M2AP_MBMS_SCHEDULING_INFORMATION(msg_p),m2ap_mbms_scheduling_information_local,sizeof(m2ap_mbms_scheduling_information_t)); else @@ -257,7 +257,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SESSION_START_REQ); + msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_MBMS_SESSION_START_REQ); itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -266,7 +266,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MBMS_SESSION_STOP_REQ); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_MBMS_SESSION_STOP_REQ); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -275,7 +275,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_MCE_CONFIGURATION_UPDATE); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_MCE_CONFIGURATION_UPDATE); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -284,7 +284,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_ENB_CONFIGURATION_UPDATE_ACK); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_ENB_CONFIGURATION_UPDATE_ACK); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -293,7 +293,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MCE_APP, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, M2AP_ENB_CONFIGURATION_UPDATE_FAILURE); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -303,7 +303,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MCE_APP, MESSAGE_TEST); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, MESSAGE_TEST); // itti_send_msg_to_task (TASK_MME_APP, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -313,7 +313,7 @@ static uint32_t MCE_app_send_m2ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MCE_APP, MESSAGE_TEST); +// msg_p = itti_alloc_new_message (TASK_MCE_APP, 0, MESSAGE_TEST); // itti_send_msg_to_task (TASK_M3AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -379,7 +379,7 @@ void *MCE_app_task(void *args_p) { do { // Wait for a message itti_receive_msg (TASK_MCE_APP, &msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -397,7 +397,7 @@ void *MCE_app_task(void *args_p) { case M3AP_REGISTER_MCE_CNF: //AssertFatal(!NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received S1AP_REGISTER_ENB_CNF\n"); - LOG_I(MCE_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_I(MCE_APP, "[MCE %ld] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), M3AP_REGISTER_MCE_CNF(msg_p).nb_mme); DevAssert(register_mce_pending > 0); register_mce_pending--; @@ -412,7 +412,7 @@ void *MCE_app_task(void *args_p) { if (registered_mce == mce_nb) { /* If all MCE are registered, start L2L1 task */ // MessageDef *msg_init_p; - // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, 0, INITIALIZE_MESSAGE); // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); } else { LOG_W(MCE_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n", @@ -434,7 +434,7 @@ void *MCE_app_task(void *args_p) { case M3AP_MBMS_SESSION_START_REQ: LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_START_REQ message %s\n", ITTI_MSG_NAME (msg_p)); - //MCE_app_handle_m3ap_mbms_session_start_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + //MCE_app_handle_m3ap_mbms_session_start_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); if(m2ap_setup_req_local) if (timer_setup (2, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL, &mce_scheduling_info_timer_id) < 0) { @@ -445,12 +445,12 @@ void *MCE_app_task(void *args_p) { case M3AP_MBMS_SESSION_STOP_REQ: LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_STOP_REQ message %s\n", ITTI_MSG_NAME (msg_p)); - MCE_app_handle_m3ap_mbms_session_stop_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + MCE_app_handle_m3ap_mbms_session_stop_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); break; case M3AP_MBMS_SESSION_UPDATE_REQ: LOG_I(MCE_APP, "Received M3AP_MBMS_SESSION_UPDATE_REQ message %s\n", ITTI_MSG_NAME (msg_p)); - MCE_app_handle_m3ap_mbms_session_update_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + MCE_app_handle_m3ap_mbms_session_update_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); break; @@ -479,7 +479,7 @@ void *MCE_app_task(void *args_p) { // /* If all MCE cells are registered, start L2L1 task */ // MessageDef *msg_init_p; - // //msg_init_p = itti_alloc_new_message (TASK_MCE_APP, INITIALIZE_MESSAGE); + // //msg_init_p = itti_alloc_new_message (TASK_MCE_APP, 0, INITIALIZE_MESSAGE); // //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); // } else { @@ -503,7 +503,7 @@ void *MCE_app_task(void *args_p) { case M3AP_DEREGISTERED_MCE_IND: if (EPC_MODE_ENABLED) { - LOG_W(MCE_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_W(MCE_APP, "[MCE %ld] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme); /* TODO handle recovering of registration */ } @@ -621,7 +621,7 @@ void *MCE_app_task(void *args_p) { m2ap_setup_req_local = (m2ap_setup_req_t*)calloc(1,sizeof(m2ap_setup_req_t)); if(m2ap_setup_req_local) memcpy(m2ap_setup_req_local,&M2AP_SETUP_REQ(msg_p),sizeof(m2ap_setup_req_t)); - MCE_app_handle_m2ap_setup_req(ITTI_MESSAGE_GET_INSTANCE(msg_p)); + MCE_app_handle_m2ap_setup_req(ITTI_MSG_DESTINATION_INSTANCE(msg_p)); //MCE_app_send_m2ap_mbms_scheduling_information(0); //if (timer_setup (2, 0, TASK_MCE_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT, // NULL, &mce_scheduling_info_timer_id) < 0) { diff --git a/openair2/MCE_APP/mce_config.c b/openair2/MCE_APP/mce_config.c index 975f524ebd..439f2d2061 100644 --- a/openair2/MCE_APP/mce_config.c +++ b/openair2/MCE_APP/mce_config.c @@ -108,7 +108,7 @@ int RCconfig_MCE(void ) { if (address) { MessageDef *message; - AssertFatal((message = itti_alloc_new_message(TASK_MCE_APP, M2AP_MCE_SCTP_REQ))!=NULL,""); + AssertFatal((message = itti_alloc_new_message(TASK_MCE_APP, 0, M2AP_MCE_SCTP_REQ))!=NULL,""); //IPV4_STR_ADDR_TO_INT_NWBO ( address, M2AP_MCE_SCTP_REQ(message).mce_m2_ip_address, "BAD IP ADDRESS FORMAT FOR MCE M2_C !\n" ); M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv6 = 0; M2AP_MCE_SCTP_REQ (message).mce_m2_ip_address.ipv4 = 1; diff --git a/openair2/NETWORK_DRIVER/LITE/device.c b/openair2/NETWORK_DRIVER/LITE/device.c index 854c3bcc99..59340784c1 100644 --- a/openair2/NETWORK_DRIVER/LITE/device.c +++ b/openair2/NETWORK_DRIVER/LITE/device.c @@ -316,7 +316,11 @@ void oai_nw_drv_change_rx_flags(struct net_device *dev, int flags) } //--------------------------------------------------------------------------- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +void oai_nw_drv_tx_timeout(struct net_device *dev, unsigned int txqueue) +#else void oai_nw_drv_tx_timeout(struct net_device *dev) +#endif { //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index 8b95e05cfc..47c68466bd 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -297,7 +297,11 @@ int nas_change_mtu(struct net_device *dev, int mtu) } //--------------------------------------------------------------------------- +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +void nas_tx_timeout(struct net_device *dev, unsigned int txqueue) +#else void nas_tx_timeout(struct net_device *dev) +#endif { //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. @@ -324,7 +328,7 @@ static const struct net_device_ops nasmesh_netdev_ops = { .ndo_set_mac_address = NULL, .ndo_set_config = nas_set_config, .ndo_do_ioctl = nas_CTL_ioctl, -#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1797) +#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1797 && LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)) .extended.ndo_change_mtu = nas_change_mtu, #else .ndo_change_mtu = nas_change_mtu, diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 86e00ef674..05118a5f6b 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -287,18 +287,6 @@ ue_ip_common_ip2wireless( printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]); } - // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start -#ifdef UESIM_EXPANSION - - if ((src_addr[3] - 2)> instP) { - pdcph.inst = src_addr[3] - 2; - printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst); - instP = src_addr[3] - 2; - priv_p=netdev_priv(ue_ip_dev[instP]); - } - -#endif - // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator end //get Ipv4 address and pass to PCDP header printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id ); printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id ); diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 32f9442747..63184eb6da 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -302,7 +302,12 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) { } //--------------------------------------------------------------------------- -void ue_ip_tx_timeout(struct net_device *dev_pP) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int txqueue) +#else +void ue_ip_tx_timeout(struct net_device *dev_pP) +#endif +{ //--------------------------------------------------------------------------- // Transmitter timeout, serious problems. ue_ip_priv_t *priv_p = netdev_priv(dev_pP); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 3070188f9e..b5cda6ecd6 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -30,12 +30,9 @@ * \warning */ -#include "openair1/PHY/defs_eNB.h" -#include "openair1/PHY/phy_extern.h" #include "openair1/SCHED_NR/fapi_nr_l1.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" -#include "LAYER2/MAC/mac_proto.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "common/ran_context.h" #include "executables/softmodem-common.h" @@ -56,135 +53,119 @@ extern uint16_t sf_ahead; extern uint16_t sl_ahead; void handle_nr_rach(NR_UL_IND_t *UL_info) { + if (UL_info->rach_ind.number_of_pdus>0) { - AssertFatal(UL_info->rach_ind.number_of_pdus==1,"More than 1 RACH pdu not supported\n"); - UL_info->rach_ind.number_of_pdus=0; - LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); - - if (UL_info->rach_ind.pdu_list[0].num_preamble>0) - AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1, - "More than 1 preamble not supported\n"); + LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); + int npdus = UL_info->rach_ind.number_of_pdus; + for(int i = 0; i < npdus; i++) { + UL_info->rach_ind.number_of_pdus--; + if (UL_info->rach_ind.pdu_list[i].num_preamble>0) + AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1, + "More than 1 preamble not supported\n"); - nr_initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - UL_info->rach_ind.sfn, - UL_info->rach_ind.slot, - UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index, - UL_info->rach_ind.pdu_list[0].freq_index, - UL_info->rach_ind.pdu_list[0].symbol_index, - UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance); - + nr_initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + UL_info->rach_ind.sfn, + UL_info->rach_ind.slot, + UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index, + UL_info->rach_ind.pdu_list[i].freq_index, + UL_info->rach_ind.pdu_list[i].symbol_index, + UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance); + } } } -void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) { - +void handle_nr_uci(NR_UL_IND_t *UL_info) +{ + const module_id_t mod_id = UL_info->module_id; + const frame_t frame = UL_info->frame; + const sub_frame_t slot = UL_info->slot; int num_ucis = UL_info->uci_ind.num_ucis; nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; for (int i = 0; i < num_ucis; i++) { switch (uci_list[i].pdu_type) { - case NFAPI_NR_UCI_PUSCH_PDU_TYPE: break; + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__); + break; case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; - - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); - - if( (uci_pdu->pduBitmap>>1) & 0x01) - nr_rx_acknack(NULL,uci_pdu,NULL,UL_info,sched_ctrl,stats); - + const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; + handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu); break; } case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4; - - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); - - if( (uci_pdu->pduBitmap>>1) & 0x01) - nr_rx_acknack(NULL,NULL,uci_pdu,UL_info,sched_ctrl,stats); - + const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4; + handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu); break; } } } UL_info->uci_ind.num_ucis = 0; + // mark corresponding PUCCH resources as free + // NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs + RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0; } -void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) { +void handle_nr_ulsch(NR_UL_IND_t *UL_info) +{ + if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) { + for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) { + for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) { + // find crc_indication j corresponding rx_indication i + const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i]; + const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j]; + LOG_D(PHY, + "UL_info->crc_ind.pdu_list[%d].rnti:%04x " + "UL_info->rx_ind.pdu_list[%d].rnti:%04x\n", + j, + crc->rnti, + i, + rx->rnti); - if(nfapi_mode == 1) { - if (UL_info->crc_ind.number_crcs>0) { - //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); - // oai_nfapi_crc_indication(&UL_info->crc_ind); + if (crc->rnti != rx->rnti) + continue; - UL_info->crc_ind.number_crcs = 0; - } + LOG_D(MAC, + "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n", + UL_info->frame, + UL_info->slot, + crc->tb_crc_status ? "error" : "ok", + crc->tb_crc_status); - if (UL_info->rx_ind.number_of_pdus>0) { - //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); - // oai_nfapi_rx_ind(&UL_info->rx_ind); - UL_info->rx_ind.number_of_pdus = 0; - } - } else { + /* if CRC passes, pass PDU, otherwise pass NULL as error indication */ + nr_rx_sdu(UL_info->module_id, + UL_info->CC_id, + UL_info->rx_ind.sfn, + UL_info->rx_ind.slot, + rx->rnti, + crc->tb_crc_status ? NULL : rx->pdu, + rx->pdu_length, + rx->timing_advance, + rx->ul_cqi, + rx->rssi); + handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc); + break; + } // for (j=0;jcrc_ind.number_crcs;j++) + } // for (i=0;irx_ind.number_of_pdus;i++) - if (UL_info->rx_ind.number_of_pdus>0 && UL_info->crc_ind.number_crcs>0) { - for (int i=0; irx_ind.number_of_pdus; i++) { - for (int j=0; jcrc_ind.number_crcs; j++) { - // find crc_indication j corresponding rx_indication i - LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j, - UL_info->crc_ind.crc_list[j].rnti, i, UL_info->rx_ind.pdu_list[i].rnti); - - if (UL_info->crc_ind.crc_list[j].rnti == - UL_info->rx_ind.pdu_list[i].rnti) { - LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status); - - handle_nr_ul_harq(UL_info->slot, sched_ctrl, stats, UL_info->crc_ind.crc_list[j]); - - if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication - LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot); - - nr_rx_sdu(UL_info->module_id, - UL_info->CC_id, - UL_info->rx_ind.sfn, //UL_info->frame, - UL_info->rx_ind.slot, //UL_info->slot, - UL_info->rx_ind.pdu_list[i].rnti, - (uint8_t *)NULL, - UL_info->rx_ind.pdu_list[i].pdu_length, - UL_info->rx_ind.pdu_list[i].timing_advance, - UL_info->rx_ind.pdu_list[i].ul_cqi, - UL_info->rx_ind.pdu_list[i].rssi); - } else { - LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); - nr_rx_sdu(UL_info->module_id, - UL_info->CC_id, - UL_info->rx_ind.sfn, //UL_info->frame, - UL_info->rx_ind.slot, //UL_info->slot, - UL_info->rx_ind.pdu_list[i].rnti, - UL_info->rx_ind.pdu_list[i].pdu, - UL_info->rx_ind.pdu_list[i].pdu_length, - UL_info->rx_ind.pdu_list[i].timing_advance, - UL_info->rx_ind.pdu_list[i].ul_cqi, - UL_info->rx_ind.pdu_list[i].rssi); - } - break; - } - } // for (j=0;jcrc_ind.number_crcs;j++) - } // for (i=0;irx_ind.number_of_pdus;i++) - - UL_info->crc_ind.number_crcs=0; - UL_info->rx_ind.number_of_pdus = 0; - } - else if (UL_info->rx_ind.number_of_pdus!=0 || UL_info->crc_ind.number_crcs!=0) { - LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n", - UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot, - UL_info->crc_ind.number_crcs, UL_info->rx_ind.sfn, UL_info->rx_ind.slot); - } + UL_info->crc_ind.number_crcs = 0; + UL_info->rx_ind.number_of_pdus = 0; + } else if (UL_info->rx_ind.number_of_pdus != 0 + || UL_info->crc_ind.number_crcs != 0) { + LOG_E(PHY, + "hoping not to have mis-match between CRC ind and RX ind - " + "hopefully the missing message is coming shortly " + "rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n", + UL_info->rx_ind.number_of_pdus, + UL_info->rx_ind.sfn, + UL_info->rx_ind.slot, + UL_info->crc_ind.number_crcs, + UL_info->rx_ind.sfn, + UL_info->rx_ind.slot); } } @@ -215,14 +196,12 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ifi->CC_mask |= (1<frame,UL_info->slot); handle_nr_rach(UL_info); - handle_nr_uci(UL_info,&mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0],mac->pucch_target_snrx10); + handle_nr_uci(UL_info); // clear HI prior to handling ULSCH mac->UL_dci_req[CC_id].numPdus = 0; - handle_nr_ulsch(UL_info, &mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0]); + handle_nr_ulsch(UL_info); if (nfapi_mode != 1) { if (ifi->CC_mask == ((1<DL_req = &mac->DL_req[CC_id]; sched_info->UL_dci_req = &mac->UL_dci_req[CC_id]; - sched_info->UL_tti_req = &mac->UL_tti_req[CC_id]; + sched_info->UL_tti_req = mac->UL_tti_req[CC_id]; sched_info->TX_req = &mac->TX_req[CC_id]; #ifdef DUMP_FAPI diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 5d620181d1..edaef6d1ce 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -42,6 +42,8 @@ #define MAX_IF_MODULES 100 +const char *dl_indication_type[] = {"MIB", "SIB", "DLSCH", "DCI", "RAR"}; + static nr_ue_if_module_t *nr_ue_if_module_inst[MAX_IF_MODULES]; // L2 Abstraction Layer @@ -60,43 +62,22 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui // L2 Abstraction Layer int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len){ - - return 0; + return nr_ue_decode_sib1(module_id, cc_id, gNB_index, sibs_mask, pduP, pdu_len); } + // L2 Abstraction Layer -int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr_dci_indication_pdu_t *dci){ +int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci){ - //printf("handle_dci: rnti %x,dci_type %d\n",rnti,dci_type); - return nr_ue_process_dci_indication_pdu(module_id, cc_id, gNB_index, dci); + return nr_ue_process_dci_indication_pdu(module_id, cc_id, gNB_index, frame, slot, dci); } -// L2 Abstraction Layer -int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, uint8_t *pduP, uint32_t pdu_len, frame_t frame, int slot, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ - LOG_D(MAC, "handle_dlsch at MAC layer \n"); - //if (IS_SOFTMODEM_NOS1 || IS_SOFTMODEM_RFSIM) - // sdu should be processed even when is S1 mode because data and timing advance updates are transmitted by the UE - nr_ue_send_sdu(module_id, cc_id, frame, slot, - pduP, - pdu_len, - gNB_index, - ul_time_alignment); +// L2 Abstraction Layer +// Note: sdu should always be processed because data and timing advance updates are transmitted by the UE +int8_t handle_dlsch (nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ - return 0; - /* - return nr_ue_process_dlsch(module_id, - cc_id, - gNB_index, - dci_ind, - pduP, - pdu_len); - */ -} + nr_ue_send_sdu(dl_info, ul_time_alignment, pdu_id); -int8_t handle_rar (nr_downlink_indication_t *dl_info){ - - LOG_D(MAC, "handling RAR at MAC layer \n"); - nr_process_rar (dl_info); return 0; } @@ -110,7 +91,7 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ ret = nr_ue_scheduler(NULL, ul_info); if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra) - nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx); + nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id); switch(ret){ case UE_CONNECTION_OK: @@ -135,8 +116,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ module_id_t module_id = dl_info->module_id; 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; - + if (!dl_info->dci_ind && !dl_info->rx_ind) { // UL indication to schedule DCI reception nr_ue_scheduler(dl_info, NULL); @@ -150,13 +130,15 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ int8_t ret = handle_dci(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, + dl_info->frame, + dl_info->slot, dl_info->dci_ind->dci_list+i); ret_mask |= (ret << FAPI_NR_DCI_IND); if (ret >= 0) { AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" ); AssertFatal( nr_ue_if_module_inst[module_id]->scheduled_response != NULL, "scheduled_response is NULL!\n" ); - fill_scheduled_response(&scheduled_response, dl_config, ul_config, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot); + fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id); nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response); } } @@ -164,13 +146,17 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ if(dl_info->rx_ind != NULL){ - LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], Number of PDUs: %d \n", dl_info->rx_ind->number_pdus); - for(i=0; irx_ind->number_pdus; ++i){ + LOG_D(MAC, "In %s sending DL indication to MAC. 1 PDU type %s of %d total number of PDUs \n", + __FUNCTION__, + dl_indication_type[dl_info->rx_ind->rx_indication_body[i].pdu_type - 1], + dl_info->rx_ind->number_pdus); + switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){ case FAPI_NR_RX_PDU_TYPE_MIB: + ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.pdu, (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.additional_bits, @@ -178,8 +164,6 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.ssb_length, (dl_info->rx_ind->rx_indication_body+i)->mib_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_MIB; - LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], MIB case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus); - break; case FAPI_NR_RX_PDU_TYPE_SIB: @@ -194,26 +178,18 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ case FAPI_NR_RX_PDU_TYPE_DLSCH: - ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, - dl_info->dci_ind, - (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu, - (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length, - dl_info->frame, - dl_info->slot, - ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_DLSCH; - - LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][RX_IND], DLSCH case Number of PDUs: %d \n", dl_info->rx_ind->number_pdus); + ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH; break; case FAPI_NR_RX_PDU_TYPE_RAR: - ret_mask |= (handle_rar(dl_info)) << FAPI_NR_RX_PDU_TYPE_RAR; + ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR; break; default: - break; + break; } } } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index df2d78f0cb..e78529d437 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -66,8 +66,8 @@ typedef struct { frame_t frame; /// slot int slot; - /// proc is needed to signal back decoded frame number to PHY. However, this is not really FAPI procedure and should be done differently - UE_nr_rxtx_proc_t * proc; + /// index of the current UE RX/TX thread + int thread_id; /// NR UE FAPI-like P7 message, direction: L1 to L2 /// data reception indication structure @@ -95,6 +95,9 @@ typedef struct { frame_t frame_tx; /// slot tx uint32_t slot_tx; + /// index of the current UE RX/TX thread + int thread_id; + /// dci reception indication structure fapi_nr_dci_indication_t *dci_ind; } nr_uplink_indication_t; @@ -111,6 +114,8 @@ typedef struct { frame_t frame; /// slot int slot; + /// index of the current UE RX/TX thread + int thread_id; /// NR UE FAPI-like P7 message, direction: L2 to L1 /// downlink transmission configuration request structure @@ -224,7 +229,7 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, ui \param pduP pointer to pdu*/ int handle_bcch_dlsch(module_id_t module_id, int cc_id, unsigned int gNB_index, uint32_t sibs_mask, uint8_t *pduP, uint32_t pdu_len); -int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, fapi_nr_dci_indication_pdu_t *dci); +int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); #endif diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 42a4459732..1470cbc006 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -203,17 +203,6 @@ typedef struct IF_Module_s{ pthread_mutex_t if_mutex; } IF_Module_t; -// These mutex is used for multiple UEs L2 FAPI simulator. -// Each UEs set these value in UL and UL_INFO is shared in all UE's thread. -typedef struct { - pthread_mutex_t rx_mutex; - pthread_mutex_t crc_mutex; - pthread_mutex_t sr_mutex; - pthread_mutex_t harq_mutex; - pthread_mutex_t cqi_mutex; - pthread_mutex_t rach_mutex; -} FILL_UL_INFO_MUTEX_t; - /*Initial */ IF_Module_t *IF_Module_init(int Mod_id); void IF_Module_kill(int Mod_id); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index de42d67624..b4a7f8c6e7 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -64,8 +64,6 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id, nfapi_rx_indication_pdu_t *pdu; int timing_advance_update; - pthread_mutex_lock(&fill_ul_mutex.rx_mutex); - UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe; UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; UL_INFO->rx_ind.vendor_extension = ul_config_req->vendor_extension; @@ -101,7 +99,6 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id, UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe; - pthread_mutex_unlock(&fill_ul_mutex.rx_mutex); } void fill_sr_indication_UE_MAC(int Mod_id, @@ -109,8 +106,6 @@ void fill_sr_indication_UE_MAC(int Mod_id, int subframe, UL_IND_t *UL_INFO, uint16_t rnti) { - pthread_mutex_lock(&fill_ul_mutex.sr_mutex); - nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind; nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; @@ -139,7 +134,6 @@ void fill_sr_indication_UE_MAC(int Mod_id, // UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; sr_ind_body->number_of_srs++; - pthread_mutex_unlock(&fill_ul_mutex.sr_mutex); } void fill_crc_indication_UE_MAC(int Mod_id, @@ -149,8 +143,6 @@ void fill_crc_indication_UE_MAC(int Mod_id, uint8_t crc_flag, int index, uint16_t rnti) { - pthread_mutex_lock(&fill_ul_mutex.crc_mutex); - nfapi_crc_indication_pdu_t *pdu = &UL_INFO->crc_ind.crc_indication_body .crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs]; @@ -174,8 +166,6 @@ void fill_crc_indication_UE_MAC(int Mod_id, __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); - - pthread_mutex_unlock(&fill_ul_mutex.crc_mutex); } void fill_rach_indication_UE_MAC(int Mod_id, @@ -184,10 +174,6 @@ void fill_rach_indication_UE_MAC(int Mod_id, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) { - LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n"); - - pthread_mutex_lock(&fill_ul_mutex.rach_mutex); - UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1; UL_INFO->rach_ind.header.message_id = NFAPI_RACH_INDICATION; @@ -232,8 +218,6 @@ void fill_rach_indication_UE_MAC(int Mod_id, // should call it when we merge with that branch. oai_nfapi_rach_ind(&UL_INFO->rach_ind); free(UL_INFO->rach_ind.rach_indication_body.preamble_list); - - pthread_mutex_unlock(&fill_ul_mutex.rach_mutex); } void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, @@ -241,7 +225,6 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) { - pthread_mutex_lock(&fill_ul_mutex.cqi_mutex); nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_indication_body .cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; @@ -275,7 +258,6 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, raw_pdu->pdu[0] = cqi << 4; UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis++; - pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex); } void fill_ulsch_harq_indication_UE_MAC( @@ -285,8 +267,6 @@ void fill_ulsch_harq_indication_UE_MAC( UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti) { - pthread_mutex_lock(&fill_ul_mutex.harq_mutex); - nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list [UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; @@ -318,7 +298,6 @@ void fill_ulsch_harq_indication_UE_MAC( } UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; - pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); } void fill_uci_harq_indication_UE_MAC(int Mod_id, @@ -327,8 +306,6 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, UL_IND_t *UL_INFO, nfapi_ul_config_harq_information *harq_information, uint16_t rnti) { - pthread_mutex_lock(&fill_ul_mutex.harq_mutex); - nfapi_harq_indication_t *ind = &UL_INFO->harq_ind; nfapi_harq_indication_body_t *body = &ind->harq_indication_body; nfapi_harq_indication_pdu_t *pdu = @@ -410,7 +387,6 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, LOG_D(PHY, "Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs); - pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); } void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h index 09356fc9f8..547fc2dfc4 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -17,8 +17,6 @@ //#include "openair1/PHY/defs.h" //#include "openair1/PHY/LTE_TRANSPORT/defs.h" -// this mutex is used to set multiple UE's UL value in L2 FAPI simulator. -FILL_UL_INFO_MUTEX_t fill_ul_mutex; //below 2 difinitions move to phy_stub_UE.c to add initialization when difinition. extern UL_IND_t *UL_INFO; extern nfapi_tx_request_pdu_t* tx_request_pdu_list; diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index fa332b5be1..f70cc68550 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -80,7 +80,7 @@ rrc_data_req( ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ); RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; @@ -139,7 +139,7 @@ rrc_data_ind( uint8_t *message_buffer; message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, 0, RRC_DCCH_DATA_IND); RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; RRC_DCCH_DATA_IND (message_p).sdu_size = sdu_sizeP; diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 8c55dbaeb5..5c1800cdd4 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -94,7 +94,7 @@ mac_rrc_data_req_ue( ccch_size = sdu_size; } - message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ); + message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_MAC_CCCH_DATA_REQ); RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP; RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size; memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE); @@ -155,7 +155,7 @@ mac_rrc_data_ind_ue( sdu_size = sdu_lenP; } - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_MBMS_DATA_IND); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_BCCH_MBMS_DATA_IND); memset (RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sdu, 0, BCCH_SDU_MBMS_SIZE); RRC_MAC_BCCH_MBMS_DATA_IND (message_p).frame = frameP; RRC_MAC_BCCH_MBMS_DATA_IND (message_p).sub_frame = sub_frameP; @@ -181,7 +181,7 @@ mac_rrc_data_ind_ue( sdu_size = sdu_lenP; } - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_BCCH_DATA_IND); memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); RRC_MAC_BCCH_DATA_IND (message_p).frame = frameP; RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP; @@ -213,7 +213,7 @@ mac_rrc_data_ind_ue( sdu_size = sdu_lenP; } - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_CCCH_DATA_IND); memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size); RRC_MAC_CCCH_DATA_IND (message_p).frame = frameP; @@ -239,7 +239,7 @@ mac_rrc_data_ind_ue( sdu_size = msg_sdu_size; } - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_MCCH_DATA_IND); RRC_MAC_MCCH_DATA_IND (message_p).frame = frameP; RRC_MAC_MCCH_DATA_IND (message_p).sub_frame = sub_frameP; RRC_MAC_MCCH_DATA_IND (message_p).sdu_size = sdu_lenP; @@ -293,7 +293,7 @@ rrc_data_req_ue( ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ); RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; @@ -332,7 +332,7 @@ rrc_data_ind_ue( uint8_t *message_buffer; message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP); memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, 0, RRC_DCCH_DATA_IND); RRC_DCCH_DATA_IND (message_p).frame = ctxt_pP->frame; RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index; RRC_DCCH_DATA_IND (message_p).sdu_size = sdu_sizeP; @@ -350,7 +350,7 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) { { MessageDef *message_p; //LOG_I(RRC,"sending a message to task_mac_ue\n"); - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_IN_SYNC_IND); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_IN_SYNC_IND); RRC_MAC_IN_SYNC_IND (message_p).frame = frameP; RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index; itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); @@ -370,7 +370,7 @@ void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index { MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_OUT_OF_SYNC_IND); RRC_MAC_OUT_OF_SYNC_IND (message_p).frame = frameP; RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index; itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); @@ -396,7 +396,7 @@ int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index) { //-------------------------------------------------------------------------------------------// { MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF); + message_p = itti_alloc_new_message (TASK_MAC_UE, 0, RRC_MAC_CCCH_DATA_CNF); RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index; itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p); } diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index 06b150a673..91dc7aafd4 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -37,6 +37,9 @@ #include "COMMON/s1ap_messages_types.h" #include "COMMON/rrc_messages_types.h" +#if ITTI_SIM +#include "COMMON/itti_sim_messages_types.h" +#endif #include "collection/tree.h" #include "rrc_types_NB_IoT.h" diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index c5aa2bc0f8..c57cec6ba5 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -1796,7 +1796,7 @@ rrc_ue_process_rrcConnectionReconfiguration( for (list_count = 0; list_count < rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.count; list_count++) { pdu_length = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->size; pdu_buffer = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->buf; - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_ESTABLI_CNF); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CONN_ESTABLI_CNF); NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; @@ -1811,7 +1811,7 @@ rrc_ue_process_rrcConnectionReconfiguration( MessageDef *message_ral_p = NULL; rrc_ral_connection_reestablishment_ind_t connection_reestablishment_ind; int i; - message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_REESTABLISHMENT_IND); + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_RAL_CONNECTION_REESTABLISHMENT_IND); memset(&connection_reestablishment_ind, 0, sizeof(rrc_ral_connection_reestablishment_ind_t)); // TO DO ral_si_ind.plmn_id = 0; connection_reestablishment_ind.ue_id = ctxt_pP->rnti; @@ -2007,7 +2007,7 @@ rrc_ue_decode_dcch( MessageDef *msg_p; pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size; pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf; - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_DOWNLINK_DATA_IND); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_DOWNLINK_DATA_IND); NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ? NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length; NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer; @@ -2073,7 +2073,7 @@ rrc_ue_decode_dcch( MessageDef *message_ral_p = NULL; rrc_ral_connection_reconfiguration_ho_ind_t connection_reconfiguration_ho_ind; int i; - message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND); + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_RAL_CONNECTION_RECONFIGURATION_HO_IND); memset(&connection_reconfiguration_ho_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ho_ind_t)); connection_reconfiguration_ho_ind.ue_id = ctxt_pP->module_id; @@ -2127,7 +2127,7 @@ rrc_ue_decode_dcch( MessageDef *message_ral_p = NULL; rrc_ral_connection_reconfiguration_ind_t connection_reconfiguration_ind; int i; - message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_CONNECTION_RECONFIGURATION_IND); + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_RAL_CONNECTION_RECONFIGURATION_IND); memset(&connection_reconfiguration_ind, 0, sizeof(rrc_ral_connection_reconfiguration_ind_t)); connection_reconfiguration_ind.ue_id = ctxt_pP->module_id; @@ -2189,7 +2189,7 @@ rrc_ue_decode_dcch( break; case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CONN_RELEASE_IND); if ((dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.present == LTE_RRCConnectionRelease__criticalExtensions_PR_c1) @@ -2201,7 +2201,7 @@ rrc_ue_decode_dcch( itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); #if ENABLE_RAL - msg_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_CONNECTION_RELEASE_IND); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, RRC_RAL_CONNECTION_RELEASE_IND); RRC_RAL_CONNECTION_RELEASE_IND(msg_p).ue_id = ctxt_pP->module_id; itti_send_msg_to_task(TASK_RAL_UE, ctxt_pP->instance, msg_p); #endif @@ -2837,7 +2837,7 @@ int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_in ) ) { MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CELL_SELECTION_CNF); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CELL_SELECTION_CNF); NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.cellIdentity); NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(&sib1->cellAccessRelatedInfo.trackingAreaCode); @@ -2853,7 +2853,7 @@ int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_in if (cell_valid == 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); } @@ -3036,7 +3036,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, ) { /* PLMN match, send a confirmation to NAS */ MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CELL_SELECTION_CNF); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CELL_SELECTION_CNF); NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.cellIdentity); NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(&sib1->cellAccessRelatedInfo.trackingAreaCode); @@ -3054,7 +3054,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, if (cell_valid == 0) { /* Cell can not be used, ask PHY to try the next one */ MessageDef *msg_p; - msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); + msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM " @@ -3672,7 +3672,7 @@ int decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { { MessageDef *message_ral_p = NULL; rrc_ral_system_information_ind_t ral_si_ind; - message_ral_p = itti_alloc_new_message (TASK_RRC_UE, RRC_RAL_SYSTEM_INFORMATION_IND); + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_RAL_SYSTEM_INFORMATION_IND); memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t)); ral_si_ind.plmn_id.MCCdigit2 = '0'; ral_si_ind.plmn_id.MCCdigit1 = '2'; @@ -4456,7 +4456,7 @@ void *rrc_ue_task( void *args_p ) { while(1) { // Wait for a message itti_receive_msg (TASK_RRC_UE, &msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); switch (ITTI_MSG_ID(msg_p)) { @@ -4645,7 +4645,7 @@ void *rrc_ue_task( void *args_p ) { case RRC_STATE_IDLE: { /* Ask to layer 1 to find a cell matching the criterion */ MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_CELL_REQ); + message_p = itti_alloc_new_message(TASK_RRC_UE, 0, PHY_FIND_CELL_REQ); PHY_FIND_CELL_REQ (message_p).earfcn_start = 1; PHY_FIND_CELL_REQ (message_p).earfcn_end = 1; itti_send_msg_to_task(TASK_PHY_UE, UE_MODULE_ID_TO_INSTANCE(ue_mod_id), message_p); @@ -4748,7 +4748,7 @@ void *rrc_ue_task( void *args_p ) { if (rrc_get_sub_state(ue_mod_id) != RRC_SUB_STATE_IDLE_SEARCHING) { /* Ask to layer 1 to find a cell matching the criterion */ MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_CELL_REQ); + message_p = itti_alloc_new_message(TASK_RRC_UE, 0, PHY_FIND_CELL_REQ); rrc_set_sub_state (ue_mod_id, RRC_SUB_STATE_IDLE_SEARCHING); PHY_FIND_CELL_REQ (message_p).transaction_id = RRC_RAL_SCAN_REQ (msg_p).transaction_id; PHY_FIND_CELL_REQ (message_p).earfcn_start = 1; @@ -4780,7 +4780,7 @@ void *rrc_ue_task( void *args_p ) { case RRC_SUB_STATE_IDLE_SEARCHING: { MessageDef *message_p; int i; - message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_SCAN_CONF); + message_p = itti_alloc_new_message(TASK_RRC_UE, 0, RRC_RAL_SCAN_CONF); RRC_RAL_SCAN_CONF (message_p).transaction_id = PHY_FIND_CELL_IND(msg_p).transaction_id; RRC_RAL_SCAN_CONF (message_p).num_scan_resp = PHY_FIND_CELL_IND(msg_p).cell_nb; @@ -4823,7 +4823,7 @@ void *rrc_ue_task( void *args_p ) { case PHY_MEAS_REPORT_IND: { LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_MEASUREMENT_REPORT_IND); + message_p = itti_alloc_new_message(TASK_RRC_UE, 0, RRC_RAL_MEASUREMENT_REPORT_IND); memcpy(&RRC_RAL_MEASUREMENT_REPORT_IND (message_p).threshold, &PHY_MEAS_REPORT_IND(msg_p).threshold, sizeof(RRC_RAL_MEASUREMENT_REPORT_IND (message_p).threshold)); diff --git a/openair2/RRC/LTE/rrc_UE_ral.c b/openair2/RRC/LTE/rrc_UE_ral.c index d7ace8c242..1ebba43d8b 100644 --- a/openair2/RRC/LTE/rrc_UE_ral.c +++ b/openair2/RRC/LTE/rrc_UE_ral.c @@ -126,7 +126,7 @@ int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageD message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; default: @@ -147,7 +147,7 @@ int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageD message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; default: @@ -166,7 +166,7 @@ int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageD message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_PHY_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; case RAL_LINK_PARAM_LTE_AVAILABLE_BW: @@ -176,7 +176,7 @@ int rrc_ue_ral_handle_configure_threshold_request(unsigned int mod_idP, MessageD message_p = itti_alloc_new_message (TASK_RRC_UE, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_MAC_UE, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 7829360939..7602e9ca64 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -554,7 +554,7 @@ typedef struct eNB_RRC_UE_s { LTE_DRB_ToAddModList_t *DRB_configList; LTE_DRB_ToAddModList_t *DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - uint8_t DRB_active[8]; + uint8_t DRB_active[NB_RB_MAX -2]; struct LTE_PhysicalConfigDedicated *physicalConfigDedicated; struct LTE_SPS_Config *sps_Config; LTE_MeasObjectToAddMod_t *MeasObj[MAX_MEAS_OBJ]; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 4454980e33..6d39fb2221 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -332,7 +332,7 @@ init_SI( if (carrier->MBMS_flag > 0) { for (i = 0; i < carrier->sib2->mbsfn_SubframeConfigList->list.count; i++) { // SIB 2 - // LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count); + // LOG_D(RRC, "[eNB %ld] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count); LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), i, @@ -1132,7 +1132,7 @@ void release_UE_in_freeList(module_id_t mod_id) { rrc_rlc_remove_ue(&ctxt); pdcp_remove_UE(&ctxt); } else { - MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = rnti; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release @@ -2173,7 +2173,7 @@ void rrc_generate_SgNBReleaseRequest( //----------------------------------------------------------------------------- { MessageDef *msg; - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_RELEASE_REQ); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RELEASE_REQ); memset(&(X2AP_ENDC_SGNB_RELEASE_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_release_req_t)); // X2AP_ENDC_SGNB_RELEASE_REQ(msg).MeNB_ue_x2_id = ; // X2AP_ENDC_SGNB_RELEASE_REQ(msg).SgNB_ue_x2_id = ; @@ -2268,7 +2268,7 @@ rrc_eNB_generate_RRCConnectionRelease( pthread_mutex_unlock(&rrc_release_freelist); if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release @@ -3110,7 +3110,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { /* Send DRX configuration to MAC task to configure timers of local UE context */ - message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_MAC_DRX_CONFIG_REQ); + message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, RRC_MAC_DRX_CONFIG_REQ); RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = rnti; RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; itti_send_msg_to_task(TASK_MAC_ENB, module_id, message_p); @@ -3295,7 +3295,10 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4; - MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30; + if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2 + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz120; + else + MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15 = LTE_RS_ConfigSSB_NR_r15__subcarrierSpacingSSB_r15_kHz30; MeasObj2->measObject.choice.measObjectNR_r15.quantityConfigSet_r15 = 1; MeasObj2->measObject.choice.measObjectNR_r15.ext1 = calloc(1, sizeof(struct LTE_MeasObjectNR_r15__ext1)); @@ -3306,7 +3309,11 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t if (MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15 == NULL) exit(1); MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->present = LTE_MeasObjectNR_r15__ext1__bandNR_r15_PR_setup; - MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78; + if (rrc_inst->nr_scg_ssb_freq > 2016666) //FR2 + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 261; + else + MeasObj2->measObject.choice.measObjectNR_r15.ext1->bandNR_r15->choice.setup = 78; + ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj2); } @@ -3876,7 +3883,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LOG_W(RRC, "drx_Configuration parameter is NULL, cannot configure local UE parameters or CDRX is deactivated\n"); } else { /* Send DRX configuration to MAC task to configure timers of local UE context */ - message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_MAC_DRX_CONFIG_REQ); + message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, RRC_MAC_DRX_CONFIG_REQ); RRC_MAC_DRX_CONFIG_REQ(message_p).rnti = rnti; RRC_MAC_DRX_CONFIG_REQ(message_p).drx_Configuration = mac_MainConfig->drx_Config; itti_send_msg_to_task(TASK_MAC_ENB, module_id, message_p); @@ -4020,7 +4027,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1; MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6; - //<<<<<<< HEAD MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB if (rrc_inst->carrier[0].sib1->tdd_Config!=NULL) { @@ -4422,9 +4428,9 @@ static int encode_CG_ConfigInfo( int RRC_OK = 1; int index = 0; char temp_buff[ASN_MAX_ENCODE_SIZE]; - LTE_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL; - LTE_UE_CapabilityRAT_Container_t ue_cap_rat_container_MRDC; - LTE_UE_CapabilityRAT_Container_t ue_cap_rat_container_nr; + NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL; + NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL; + NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL; int RAT_Container_count = 0; rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig)); AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config"); @@ -4497,10 +4503,6 @@ static int encode_CG_ConfigInfo( = calloc(1,sizeof(struct NR_CG_ConfigInfo_IEs)); AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo != NULL, "failed to allocate memory for cg_configinfo_IEs"); - cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->ue_CapabilityInfo - = calloc(1,sizeof( OCTET_STRING_t)); - AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo-> - ue_CapabilityInfo != NULL, "failed to allocate memory for ue_capabilityinfo"); if(ue_context_pP->ue_context.UE_Capability_MRDC) { RAT_Container_count++; @@ -4508,8 +4510,10 @@ static int encode_CG_ConfigInfo( (void *)ue_context_pP->ue_context.UE_Capability_MRDC,temp_buff,ASN_MAX_ENCODE_SIZE); AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); - ue_cap_rat_container_MRDC.rat_Type = LTE_RAT_Type_eutra_nr; - OCTET_STRING_fromBuf(&ue_cap_rat_container_MRDC.ueCapabilityRAT_Container, + ue_cap_rat_container_MRDC = calloc(1, sizeof(*ue_cap_rat_container_MRDC)); + AssertFatal(ue_cap_rat_container_MRDC != NULL,"failed to allocate memory for ue_cap_rat_container_MRDC"); + ue_cap_rat_container_MRDC->rat_Type = NR_RAT_Type_eutra_nr; + OCTET_STRING_fromBuf(&ue_cap_rat_container_MRDC->ue_CapabilityRAT_Container, (const char *)temp_buff,(enc_rval.encoded+7)>>3); memset((void *)temp_buff,0,sizeof(temp_buff)); } @@ -4520,35 +4524,30 @@ static int encode_CG_ConfigInfo( (void *)ue_context_pP->ue_context.UE_Capability_nr,temp_buff,ASN_MAX_ENCODE_SIZE); AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); - ue_cap_rat_container_nr.rat_Type = LTE_RAT_Type_nr; - OCTET_STRING_fromBuf(&ue_cap_rat_container_nr.ueCapabilityRAT_Container, + ue_cap_rat_container_nr = calloc(1, sizeof(*ue_cap_rat_container_nr)); + AssertFatal(ue_cap_rat_container_nr != NULL,"failed to allocate memory for ue_cap_rat_container_nr"); + ue_cap_rat_container_nr->rat_Type = NR_RAT_Type_nr; + OCTET_STRING_fromBuf(&ue_cap_rat_container_nr->ue_CapabilityRAT_Container, (const char *)temp_buff,(enc_rval.encoded+7)>>3); memset((void *)temp_buff,0,sizeof(temp_buff)); } - ue_cap_rat_container_list = calloc(1,sizeof(LTE_UE_CapabilityRAT_ContainerList_t)); - ue_cap_rat_container_list->list.count = RAT_Container_count; - ue_cap_rat_container_list->list.size = RAT_Container_count * sizeof(LTE_UE_CapabilityRAT_Container_t); - ue_cap_rat_container_list->list.array = calloc(RAT_Container_count,sizeof(LTE_UE_CapabilityRAT_Container_t *)); - - if(ue_context_pP->ue_context.UE_Capability_MRDC) { - ue_cap_rat_container_list->list.array[0] = calloc(1,sizeof(LTE_UE_CapabilityRAT_Container_t)); - memcpy(ue_cap_rat_container_list->list.array[0],&ue_cap_rat_container_MRDC,sizeof(LTE_UE_CapabilityRAT_Container_t)); + if (RAT_Container_count) { + cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof( OCTET_STRING_t)); + AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo-> ue_CapabilityInfo != NULL, "failed to allocate memory for ue_capabilityinfo"); + ue_cap_rat_container_list = calloc(1,sizeof(NR_UE_CapabilityRAT_ContainerList_t)); + if (ue_cap_rat_container_MRDC != NULL) + ASN_SEQUENCE_ADD(&ue_cap_rat_container_list->list, ue_cap_rat_container_MRDC); + if (ue_cap_rat_container_nr != NULL) + ASN_SEQUENCE_ADD(&ue_cap_rat_container_list->list, ue_cap_rat_container_nr); + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList,NULL, + (void *)ue_cap_rat_container_list,temp_buff,ASN_MAX_ENCODE_SIZE); + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->ue_CapabilityInfo, + (const char *)temp_buff, (enc_rval.encoded+7)>>3); } - if(ue_context_pP->ue_context.UE_Capability_nr) { - ue_cap_rat_container_list->list.array[1] = calloc(1,sizeof(LTE_UE_CapabilityRAT_Container_t)); - memcpy(ue_cap_rat_container_list->list.array[1],&ue_cap_rat_container_nr,sizeof(LTE_UE_CapabilityRAT_Container_t)); - } - - //this xer_fprint logs can be enabled for additional debugging logs - //xer_fprint(stdout,&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,ue_cap_rat_container_list); - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,NULL, - (void *)ue_cap_rat_container_list,temp_buff,ASN_MAX_ENCODE_SIZE); - AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->ue_CapabilityInfo, - (const char *)temp_buff, (enc_rval.encoded+7)>>3); cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config = calloc(1,sizeof(OCTET_STRING_t)); AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo-> @@ -4567,7 +4566,7 @@ static int encode_CG_ConfigInfo( *enc_size = (enc_rval.encoded+7)/8; ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig,rb_config); ASN_STRUCT_FREE(asn_DEF_NR_CG_ConfigInfo,cg_configinfo); - ASN_STRUCT_FREE(asn_DEF_LTE_UE_CapabilityRAT_ContainerList,ue_cap_rat_container_list); + ASN_STRUCT_FREE(asn_DEF_NR_UE_CapabilityRAT_ContainerList,ue_cap_rat_container_list); return RRC_OK; } //----------------------------------------------------------------------------- @@ -4635,6 +4634,7 @@ rrc_eNB_process_MeasurementReport( case 7: LOG_D(RRC, "NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe); + printf("NR event frame %d subframe %d\n", ctxt_pP->frame, ctxt_pP->subframe); break; default: @@ -4663,7 +4663,7 @@ rrc_eNB_process_MeasurementReport( if(encode_CG_ConfigInfo(enc_buf,sizeof(enc_buf),ue_context_pP,&enc_size) == RRC_OK) LOG_I(RRC,"CG-ConfigInfo encoded successfully\n"); - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ); memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t)); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size); @@ -4759,7 +4759,7 @@ rrc_eNB_process_MeasurementReport( ue_context_pP->ue_context.Status = RRC_HO_EXECUTION; ue_context_pP->ue_context.handover_info->state = HO_REQUEST; /* HO Preparation message */ - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ); rrc_eNB_generate_HandoverPreparationInformation( ue_context_pP, X2AP_HANDOVER_REQ(msg).rrc_buffer, @@ -5008,11 +5008,11 @@ void rrc_eNB_handover_ue_context_release( //MessageDef *msg_release_p = NULL; MessageDef *msg_delete_tunnels_p = NULL; uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE); + //msg_release_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE); //itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_release_p); s1ap_ue_context_release(ctxt_pP->instance, ue_context_p->ue_context.eNB_ue_s1ap_id); //MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0; @@ -5089,7 +5089,7 @@ flexran_rrc_eNB_trigger_handover (int mod_id, ue_context_pP->ue_context.Status = RRC_HO_EXECUTION; ue_context_pP->ue_context.handover_info->state = HO_REQUEST; /* HO Preparation message */ - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ); rrc_eNB_generate_HandoverPreparationInformation( ue_context_pP, X2AP_HANDOVER_REQ(msg).rrc_buffer, @@ -5176,7 +5176,7 @@ check_handovers( MessageDef *msg; // Configure target ue_context_p->ue_context.handover_info->state = HO_FORWARDING; - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_HANDOVER_REQ_ACK); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ_ACK); rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size); rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP); @@ -5220,11 +5220,11 @@ check_handovers( GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).frame, 0, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).eNB_index); - LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %ld, muiP %d, confirmP %d, mode %d\n", + LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %ld, 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), - ITTI_MSG_INSTANCE (msg_p), + ITTI_MSG_DESTINATION_INSTANCE (msg_p), GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, @@ -5288,11 +5288,11 @@ check_handovers( GTPV1U_ENB_END_MARKER_IND (msg_p).frame, 0, GTPV1U_ENB_END_MARKER_IND (msg_p).eNB_index); - LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %ld, muiP %d, confirmP %d, mode %d\n", + LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %ld, 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), - ITTI_MSG_INSTANCE (msg_p), + ITTI_MSG_DESTINATION_INSTANCE (msg_p), GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, @@ -6704,22 +6704,10 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ); } } else { // remove LCHAN from MAC/PHY - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { - // DRB has just been removed so remove RLC + PDCP for DRB - /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, - (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); - */ - if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - rrc_rlc_config_req(ctxt_pP, - SRB_FLAG_NO, - MBMS_FLAG_NO, - CONFIG_ACTION_REMOVE, - DRB2LCHAN[i], - Rlc_info_um); - } + if (DRB_configList->list.array[i]->logicalChannelIdentity) { + DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->logicalChannelIdentity; } - ue_context_pP->ue_context.DRB_active[drb_id] = 0; LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); @@ -6853,7 +6841,7 @@ rrc_eNB_generate_RRCConnectionSetup( case ngran_gNB_CU : // create an ITTI message /* TODO: F1 IDs ar missing in RRC */ - message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_DL_RRC_MESSAGE); + message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, F1AP_DL_RRC_MESSAGE); F1AP_DL_RRC_MESSAGE (message_p).rrc_container = (uint8_t *)ue_p->Srb0.Tx_buffer.Payload; F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size; F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; @@ -6965,7 +6953,7 @@ void rrc_eNB_process_reconfiguration_complete_endc(const protocol_ctxt_t *const { MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_ENDC_SGNB_RECONF_COMPLETE); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RECONF_COMPLETE); /* MeNB_ue_x2_id is unknown, set to 0. * This is not correct but X2 id in the eNB is only 12 bits, @@ -7078,7 +7066,7 @@ char openair_rrc_eNB_configuration( LOG_W(RRC, "[inst %d] RRC->MCC/MSG->MCC %d/%d \n", ctxt.module_id, RC.rrc[ctxt.module_id]->mcc, rrc_configuration_req->mcc); */ if (NODE_IS_CU(RC.rrc[ctxt.module_id]->node_type)) - // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SCTP_REQ); + // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, F1AP_SCTP_REQ); // RCconfig_CU_F1(msg_p, enb_id); setup_ngran_CU(RC.rrc[ctxt.module_id]); @@ -7459,7 +7447,7 @@ rrc_eNB_decode_ccch( if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); } else { - MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release @@ -7563,7 +7551,7 @@ rrc_eNB_decode_ccch( if (NODE_IS_MONOLITHIC(RC.rrc[ctxt_pP->module_id]->node_type)) rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti); else if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { - MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, F1AP_UE_CONTEXT_RELEASE_CMD); + MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release @@ -7884,6 +7872,7 @@ rrc_eNB_decode_dcch( if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension ->scg_ConfigResponseNR_r15!=NULL) { + dedicated_DRB = -1; /* put a value that does not run anything below */ ue_context_p->ue_context.Status = RRC_NR_NSA_RECONFIGURED; /*Trigger E-RAB Modification Indication */ rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p); @@ -7946,7 +7935,7 @@ rrc_eNB_decode_dcch( xid = ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier; ue_context_p->ue_context.e_rab_release_command_flag = 0; //gtp tunnel delete - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0; @@ -8628,7 +8617,7 @@ void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { // prepare F1_SETUP_RESPONSE if (msg_p == NULL) { - msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_RESP); + msg_p = itti_alloc_new_message (TASK_CU_F1, 0,F1AP_SETUP_RESP); } F1AP_SETUP_RESP (msg_p).gNB_CU_name = rrc->node_name; @@ -8664,7 +8653,7 @@ void handle_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { if (found_cell==0) { AssertFatal(1==0,"No cell found\n"); - /*msg_p = itti_alloc_new_message (TASK_CU_F1,F1AP_SETUP_FAILURE); + /*msg_p = itti_alloc_new_message (TASK_CU_F1, 0,F1AP_SETUP_FAILURE); F1AP_SETUP_RESP (msg_p).cause = rrc->node_name; F1AP_SETUP_RESP (msg_p).time_to_wait = rrc->node_id; F1AP_SETUP_RESP (msg_p).criticality_diagnostics = rrc->node_name;*/ @@ -8853,7 +8842,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { if (RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2) { /* send a tick to x2ap */ - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_SUBFRAME_PROCESS); itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); check_handovers(ctxt_pP); // counter, get the value and aggregate } @@ -9045,7 +9034,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { if (ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA || ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA_RECONFIGURED) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_RELEASE_REQUEST); + message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_RELEASE_REQUEST); X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).rnti = ue_to_be_removed[cur_ue]->ue_context.gnb_rnti; X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).assoc_id = ue_to_be_removed[cur_ue]->ue_context.gnb_x2_assoc_id; X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).cause = X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST; @@ -9292,7 +9281,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { // Wait for a message itti_receive_msg(TASK_RRC_ENB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); - instance = ITTI_MSG_INSTANCE(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) @@ -9305,7 +9294,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case MESSAGE_TEST: - LOG_I(RRC, "[eNB %d] Received %s\n", instance, msg_name_p); + LOG_I(RRC, "[eNB %ld] Received %s\n", instance, msg_name_p); break; /* Messages from MAC */ @@ -9316,7 +9305,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { RRC_MAC_CCCH_DATA_IND(msg_p).rnti, msg_p->ittiMsgHeader.lte_time.frame, msg_p->ittiMsgHeader.lte_time.slot); - LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", + LOG_I(RRC,"Decoding CCCH : inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", instance, RRC_MAC_CCCH_DATA_IND(msg_p).CC_id, &ctxt, @@ -9374,13 +9363,13 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case S1AP_PAGING_IND: - LOG_D(RRC, "[eNB %d] Received Paging message from S1AP: %s\n", instance, msg_name_p); + LOG_D(RRC, "[eNB %ld] Received Paging message from S1AP: %s\n", instance, msg_name_p); rrc_eNB_process_PAGING_IND(msg_p, msg_name_p, instance); break; case S1AP_E_RAB_SETUP_REQ: rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(msg_p, msg_name_p, instance); - LOG_D(RRC, "[eNB %d] Received the message %s\n", instance, msg_name_p); + LOG_D(RRC, "[eNB %ld] Received the message %s\n", instance, msg_name_p); break; case S1AP_E_RAB_MODIFY_REQ: @@ -9414,7 +9403,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { } case S1AP_PATH_SWITCH_REQ_ACK: - LOG_I(RRC, "[eNB %d] received path switch ack %s\n", instance, msg_name_p); + LOG_I(RRC, "[eNB %ld] received path switch ack %s\n", instance, msg_name_p); rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK(msg_p, msg_name_p, instance); break; @@ -9427,7 +9416,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case X2AP_HANDOVER_REQ: - LOG_I(RRC, "[eNB %d] target eNB Receives X2 HO Req %s\n", instance, msg_name_p); + LOG_I(RRC, "[eNB %ld] target eNB Receives X2 HO Req %s\n", instance, msg_name_p); rrc_eNB_process_handoverPreparationInformation(instance, &X2AP_HANDOVER_REQ(msg_p)); break; @@ -9445,7 +9434,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { exit(1); } - LOG_I(RRC, "[eNB %d] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p); + LOG_I(RRC, "[eNB %ld] source eNB receives the X2 HO ACK %s\n", instance, msg_name_p); DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_REQUEST) abort(); @@ -9496,7 +9485,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { case X2AP_UE_CONTEXT_RELEASE: { struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], X2AP_UE_CONTEXT_RELEASE(msg_p).rnti); - LOG_I(RRC, "[eNB %d] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p); + LOG_I(RRC, "[eNB %ld] source eNB receives the X2 UE CONTEXT RELEASE %s\n", instance, msg_name_p); DevAssert(ue_context_p != NULL); if (ue_context_p->ue_context.handover_info->state != HO_COMPLETE) abort(); @@ -9527,7 +9516,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { if (ue_context_p != NULL && ue_context_p->ue_context.handover_info != NULL) { - LOG_I(RRC, "[eNB %d] eNB receives X2 HANDOVER CANCEL for rnti %x, cause %s [%s]\n", + LOG_I(RRC, "[eNB %ld] eNB receives X2 HANDOVER CANCEL for rnti %x, cause %s [%s]\n", instance, X2AP_HANDOVER_CANCEL(msg_p).rnti, cause, @@ -9552,7 +9541,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { else failure_cause = "UE not in handover"; - LOG_W(RRC, "[eNB %d] cannot process (%s) X2 HANDOVER CANCEL for rnti %x, cause %s, ignoring\n", + LOG_W(RRC, "[eNB %ld] cannot process (%s) X2 HANDOVER CANCEL for rnti %x, cause %s, ignoring\n", instance, failure_cause, X2AP_HANDOVER_CANCEL(msg_p).rnti, cause); } @@ -9580,7 +9569,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { /* Messages from eNB app */ case RRC_CONFIGURATION_REQ: - LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p)); + LOG_I(RRC, "[eNB %ld] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p)); openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p)); break; @@ -9588,7 +9577,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { case F1AP_SETUP_REQ: AssertFatal(NODE_IS_CU(RC.rrc[instance]->node_type), "should not receive F1AP_SETUP_REQUEST, need call by CU!\n"); - LOG_I(RRC,"[eNB %d] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p)); + LOG_I(RRC,"[eNB %ld] Received %s : %p\n", instance, msg_name_p, &F1AP_SETUP_REQ(msg_p)); handle_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); break; @@ -9641,7 +9630,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; default: - LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p); + LOG_E(RRC, "[eNB %ld] Received unexpected message %s\n", instance, msg_name_p); break; } @@ -10015,7 +10004,7 @@ rrc_rx_tx( //----------------------------------------------------------------------------- { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_ENB, RRC_SUBFRAME_PROCESS); + message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, RRC_SUBFRAME_PROCESS); RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt_pP; RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; itti_send_msg_to_task(TASK_RRC_ENB, ctxt_pP->module_id, message_p); diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 5c25d2dbcf..e974a28f68 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -126,7 +126,7 @@ gtpv_data_req( memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_IND); + message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND); GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame; GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag; GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP; @@ -149,7 +149,7 @@ gtpv_data_req( memcpy (message_buffer, buffer_pP, sdu_sizeP); - message_p = itti_alloc_new_message (TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_IND); + message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND); GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame; GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag; GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP; @@ -186,7 +186,7 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", ue_context_pP->ue_context.eNB_ue_s1ap_id); - MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti; GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).from_gnb = 0; diff --git a/openair2/RRC/LTE/rrc_eNB_M2AP.c b/openair2/RRC/LTE/rrc_eNB_M2AP.c index 98a72895a0..a9c65eae1a 100644 --- a/openair2/RRC/LTE/rrc_eNB_M2AP.c +++ b/openair2/RRC/LTE/rrc_eNB_M2AP.c @@ -1520,7 +1520,7 @@ rrc_eNB_process_M2AP_MBMS_SCHEDULING_INFORMATION( rrc_M2AP_openair_rrc_top_init_MBMS(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag); }*/ MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); pthread_mutex_unlock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); @@ -1560,7 +1560,7 @@ rrc_eNB_process_M2AP_MBMS_SESSION_START_REQ( pthread_mutex_unlock(&RC.rrc[ctxt_pP->module_id]->cell_info_mutex); MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_START_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, M2AP_MBMS_SESSION_START_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -1628,7 +1628,7 @@ void rrc_eNB_send_M2AP_MBMS_SCHEDULING_INFORMATION_RESP( ) { MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, M2AP_MBMS_SCHEDULING_INFORMATION_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); } @@ -1638,7 +1638,7 @@ void rrc_eNB_send_M2AP_MBMS_SESSION_START_RESP( ) { MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_START_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, M2AP_MBMS_SESSION_START_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); } @@ -1648,7 +1648,7 @@ void rrc_eNB_send_M2AP_MBMS_SESSION_STOP_RESP( ) { MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_STOP_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, M2AP_MBMS_SESSION_STOP_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); } @@ -1658,6 +1658,6 @@ void rrc_eNB_send_M2AP_MBMS_SESSION_UPDATE_RESP( ) { MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, M2AP_MBMS_SESSION_UPDATE_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, M2AP_MBMS_SESSION_UPDATE_RESP); itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->instance), msg_p); } diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 4be9a50b32..320004a361 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -241,7 +241,7 @@ rrc_eNB_S1AP_get_ue_ids( if (s1ap_eNB_instance_p != NULL) { ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context } else { - LOG_E(S1AP, "[eNB instance %d] Couldn't find the eNB S1AP context\n", + LOG_E(S1AP, "[eNB instance %ld] Couldn't find the eNB S1AP context\n", instance); return NULL; } @@ -588,7 +588,7 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( int e_rab; int e_rabs_done = 0; int e_rabs_failed = 0; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_INITIAL_CONTEXT_SETUP_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_INITIAL_CONTEXT_SETUP_RESP); S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) { @@ -648,7 +648,7 @@ rrc_eNB_send_S1AP_UPLINK_NAS( MessageDef *msg_p; pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size; pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UPLINK_NAS); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_UPLINK_NAS); S1AP_UPLINK_NAS (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; @@ -700,7 +700,7 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( if (ret.encoded == -1) abort(); MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CAPABILITIES_IND); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_UE_CAPABILITIES_IND); S1AP_UE_CAPABILITIES_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = (ret.encoded+7)/8; S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = buf2; @@ -724,7 +724,7 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( MessageDef *message_p = NULL; rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; hashtable_rc_t h_rc; - message_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_NAS_FIRST_REQ); + message_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_NAS_FIRST_REQ); memset(&message_p->ittiMsg.s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t)); ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); S1AP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; @@ -853,7 +853,7 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( ue_initial_id = S1AP_DOWNLINK_NAS (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d\n", + LOG_I(RRC, "[eNB %ld] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d\n", instance, msg_name, ue_initial_id, @@ -871,8 +871,8 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( eNB_ue_s1ap_id); /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p; - LOG_W(RRC, "[eNB %d] In S1AP_DOWNLINK_NAS: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_NON_DELIVERY_IND); + LOG_W(RRC, "[eNB %ld] In S1AP_DOWNLINK_NAS: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_NAS_NON_DELIVERY_IND); S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.length = S1AP_DOWNLINK_NAS (msg_p).nas_pdu.length; S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.buffer = S1AP_DOWNLINK_NAS (msg_p).nas_pdu.buffer; @@ -944,14 +944,14 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char ue_initial_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", + LOG_I(RRC, "[eNB %ld] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_INITIAL_CONTEXT_SETUP_FAIL); + LOG_W(RRC, "[eNB %ld] In S1AP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_INITIAL_CONTEXT_SETUP_FAIL); S1AP_INITIAL_CONTEXT_SETUP_FAIL (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; // TODO add failure cause when defined! itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); @@ -1057,7 +1057,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char (RC.rrc[ctxt.module_id]->node_type == ngran_ng_eNB_CU) || (RC.rrc[ctxt.module_id]->node_type == ngran_gNB_CU) ){ - message_p = itti_alloc_new_message (TASK_RRC_ENB, F1AP_UE_CONTEXT_SETUP_REQ); + message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_SETUP_REQ); F1AP_UE_CONTEXT_SETUP_REQ (message_p).rrc_container = ue_p->Srb0.Tx_buffer.Payload; F1AP_UE_CONTEXT_SETUP_REQ (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size; @@ -1088,8 +1088,8 @@ int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p; - LOG_W(RRC, "[eNB %d] In S1AP_UE_CTXT_MODIFICATION_REQ: unknown UE from eNB_ue_s1ap_id (%d)\n", instance, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CTXT_MODIFICATION_FAIL); + LOG_W(RRC, "[eNB %ld] In S1AP_UE_CTXT_MODIFICATION_REQ: unknown UE from eNB_ue_s1ap_id (%d)\n", instance, eNB_ue_s1ap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_UE_CTXT_MODIFICATION_FAIL); S1AP_UE_CTXT_MODIFICATION_FAIL (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; // TODO add failure cause when defined! itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); @@ -1126,7 +1126,7 @@ int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char /* Send the response */ { MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CTXT_MODIFICATION_RESP); + msg_resp_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CTXT_MODIFICATION_RESP); S1AP_UE_CTXT_MODIFICATION_RESP(msg_resp_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; itti_send_msg_to_task(TASK_S1AP, instance, msg_resp_p); } @@ -1144,10 +1144,10 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char * if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p; - LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_REQ: unknown UE from eNB_ue_s1ap_id (%d)\n", + LOG_W(RRC, "[eNB %ld] In S1AP_UE_CONTEXT_RELEASE_REQ: unknown UE from eNB_ue_s1ap_id (%d)\n", instance, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */ + msg_fail_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */ S1AP_UE_CONTEXT_RELEASE_RESP(msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; // TODO add failure cause when defined! itti_send_msg_to_task(TASK_S1AP, instance, msg_fail_p); @@ -1157,7 +1157,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char * /* Send the response */ { MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_RESP); + msg_resp_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE_RESP); S1AP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; itti_send_msg_to_task(TASK_S1AP, instance, msg_resp_p); } @@ -1187,7 +1187,7 @@ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( "0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ", ue_context_pP->ue_context.eNB_ue_s1ap_id); MessageDef *msg_context_release_req_p = NULL; - msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_REQ); + msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE_REQ); S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause = causeP; S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP; @@ -1202,7 +1202,7 @@ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT( MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", eNB_ue_s1ap_id); - MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE_COMPLETE); S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg).eNB_ue_s1ap_id = eNB_ue_s1ap_id; itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg); } @@ -1229,7 +1229,7 @@ rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( if (ue_context_p == NULL) { /* Can not associate this message to an UE index */ MessageDef *msg_complete_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n", + LOG_W(RRC, "[eNB %ld] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n", instance, eNB_ue_s1ap_id); MSC_LOG_EVENT(MSC_RRC_ENB, "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" context not found", @@ -1240,7 +1240,7 @@ rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( 0, "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", eNB_ue_s1ap_id); - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, 0, S1AP_UE_CONTEXT_RELEASE_COMPLETE); S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; itti_send_msg_to_task(TASK_S1AP, instance, msg_complete_p); rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); @@ -1271,14 +1271,14 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name ue_initial_id = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", + LOG_I(RRC, "[eNB %ld] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_E_RAB_SETUP_REQ (msg_p).nb_e_rabs_tosetup); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_SETUP_REQUEST_FAIL); + LOG_W(RRC, "[eNB %ld] In S1AP_E_RAB_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_SETUP_REQUEST_FAIL); S1AP_E_RAB_SETUP_REQ (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; // TODO add failure cause when defined! itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); @@ -1370,7 +1370,7 @@ int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, int e_rab; int e_rabs_done = 0; int e_rabs_failed = 0; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_SETUP_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_SETUP_RESP); S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) { @@ -1446,15 +1446,15 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_initial_id = S1AP_E_RAB_MODIFY_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_D(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", + LOG_D(RRC, "[eNB %ld] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ - LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_MODIFY_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); + LOG_W(RRC, "[eNB %ld] In S1AP_E_RAB_MODIFY_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); int nb_of_e_rabs_failed = 0; MessageDef *msg_fail_p = NULL; - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); + msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_MODIFY_RESP); S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0; @@ -1567,7 +1567,7 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam { int nb_of_e_rabs_failed = 0; MessageDef *msg_fail_p = NULL; - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); + msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_MODIFY_RESP); S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id; // S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB]; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0; @@ -1597,7 +1597,7 @@ int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t *const ctxt_pP, int e_rab; int e_rabs_done = 0; int e_rabs_failed = 0; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_MODIFY_RESP); S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_modify_e_rabs; e_rab++) { @@ -1748,7 +1748,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(&ctxt, ue_context_p, xid, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.length, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.buffer); } else { //gtp tunnel delete - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0; @@ -1779,7 +1779,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t xid) { int e_rabs_released = 0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_RELEASE_RESPONSE); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_RELEASE_RESPONSE); S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; for (int i = 0; i < NB_RB_MAX; i++) { @@ -1822,7 +1822,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance uint32_t T; /* DRX cycle */ for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) { - LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, + LOG_D(RRC,"[eNB %ld] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]); for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) { @@ -1884,7 +1884,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance default: /* pcch_nB error */ - LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", + LOG_E(RRC, "[eNB %ld] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", instance, pcch_nB); return (-1); } @@ -1920,12 +1920,12 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { //paging exist UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + LOG_D(RRC,"[eNB %ld] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); } else { /* set enable_flag */ UE_PF_PO[CC_id][i].enable_flag = TRUE; //paging new UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + LOG_D(RRC,"[eNB %ld] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); } break; @@ -1938,7 +1938,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance uint8_t *message_buffer; /* Transfer data to PDCP */ MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); + message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, RRC_PCCH_DATA_REQ); /* Create message for PDCP (DLInformationTransfer_t) */ length = do_Paging (instance, buffer, @@ -1959,7 +1959,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; RRC_PCCH_DATA_REQ (message_p).ue_index = i; RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; - LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); + LOG_D(RRC, "[eNB %ld] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); } } @@ -1981,7 +1981,7 @@ int rrc_eNB_send_PATH_SWITCH_REQ(const protocol_ctxt_t *const ctxt_pP, gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs]; memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t)); - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_PATH_SWITCH_REQ); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_PATH_SWITCH_REQ); ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id (ctxt_pP->module_id); S1AP_PATH_SWITCH_REQ (msg_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; rrc_ue_s1ap_ids_p = malloc(sizeof(*rrc_ue_s1ap_ids_p)); @@ -2084,7 +2084,7 @@ int rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ(instance_t instance, rrc_eNB_ue_contex } else { /* Save e RAB information for later */ { - LOG_I(RRC, "[eNB %d] rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ: rnti %u nb_of_e_rabs %d\n", + LOG_I(RRC, "[eNB %ld] rrc_eNB_process_X2AP_TUNNEL_SETUP_REQ: rnti %u nb_of_e_rabs %d\n", instance, ue_context_target_p->ue_context.rnti, ue_context_target_p->ue_context.nb_of_e_rabs); int i; memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); @@ -2144,14 +2144,14 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, ue_initial_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_PATH_SWITCH_REQ_ACK (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", + LOG_I(RRC, "[eNB %ld] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n", instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_E_RAB_SETUP_REQ (msg_p).nb_e_rabs_tosetup); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ //MessageDef *msg_fail_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_PATH_SWITCH_REQ_ACK: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - //msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_PATH_SWITCH_REQ_ACK_FAIL); + LOG_W(RRC, "[eNB %ld] In S1AP_PATH_SWITCH_REQ_ACK: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); + //msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_PATH_SWITCH_REQ_ACK_FAIL); //S1AP_PATH_SWITCH_REQ_ACK (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; // TODO add failure cause when defined! //itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); @@ -2242,7 +2242,7 @@ int rrc_eNB_process_S1AP_PATH_SWITCH_REQ_ACK (MessageDef *msg_p, int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP) { MessageDef *msg_p = NULL; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_UE_CONTEXT_RELEASE); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, X2AP_UE_CONTEXT_RELEASE); X2AP_UE_CONTEXT_RELEASE (msg_p).rnti = ue_context_pP->ue_context.rnti; X2AP_UE_CONTEXT_RELEASE (msg_p).source_assoc_id = ue_context_pP->ue_context.handover_info->assoc_id; itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); @@ -2295,7 +2295,7 @@ int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs]; memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t)); - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFICATION_IND); + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_MODIFICATION_IND); S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; diff --git a/openair2/RRC/LTE/rrc_eNB_ral.c b/openair2/RRC/LTE/rrc_eNB_ral.c index 4820e84dc0..9e1486f6d8 100644 --- a/openair2/RRC/LTE/rrc_eNB_ral.c +++ b/openair2/RRC/LTE/rrc_eNB_ral.c @@ -126,7 +126,7 @@ int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, Message message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; default: @@ -147,7 +147,7 @@ int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, Message message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; default: @@ -166,7 +166,7 @@ int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, Message message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_PHY_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; case RAL_LINK_PARAM_LTE_AVAILABLE_BW: @@ -176,7 +176,7 @@ int rrc_enb_ral_handle_configure_threshold_request(unsigned int mod_idP, Message message_p = itti_alloc_new_message (TASK_RRC_ENB, PHY_MEAS_THRESHOLD_REQ); PHY_MEAS_THRESHOLD_REQ(message_p).transaction_id = transaction_id; memcpy (&PHY_MEAS_THRESHOLD_REQ(message_p).cfg_param, (void *) link_cfg_param_p, sizeof(ral_link_cfg_param_t)); - itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_INSTANCE(msg_pP), message_p); + itti_send_msg_to_task (TASK_MAC_ENB, ITTI_MSG_DESTINATION_INSTANCE(msg_pP), message_p); break; case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: diff --git a/openair2/RRC/LTE/rrm_2_rrc_msg.c b/openair2/RRC/LTE/rrm_2_rrc_msg.c deleted file mode 100644 index 84801a16be..0000000000 --- a/openair2/RRC/LTE/rrm_2_rrc_msg.c +++ /dev/null @@ -1,187 +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 emul_interface.c - -\brief RRM interface emulation, it sends message to the RRM interface - - RRC -> RRM - - CMM -> RRM - -\author BURLOT Pascal - -\date 10/07/08 - - -\par Historique: - $Author$ $Date$ $Revision$ - $Id$ - $Log$ - -******************************************************************************* -*/ - -#include "defs.h" -#include "extern.h" - - - - -//#include "mac_lchan_interface.h" -//#include "openair_rrc_utils.h" -//#include "openair_rrc_main.h" -#ifdef PHY_EMUL - #include "SIMULATION/simulation_defs.h" - extern EMULATION_VARS *Emul_vars; - extern CH_MAC_INST *CH_mac_inst; - extern UE_MAC_INST *UE_mac_inst; -#endif - - - -/******************************************************************************/ -void fn_rrc (void) { - /******************************************************************************/ - msg_head_t *Header ; - char *Data; - L2_ID Mac_id; - - while(1) { - Header = (msg_head_t *) recv_msg(&S_rrc) ; - - if(Header==NULL) { - break; - } - - Data_to_read=Header->size; - - if (Data_to_read > 0 ) { - Data = (char *) (Header +1) ; - } - - msg("Got MSG of Type %d on Inst %d\n",Header->msg_type,Header->inst); - - switch ( Header->msg_type ) { - case RRM_INIT_CH_REQ: { - rrm_init_ch_req_t *p = (rrm_init_ch_req_t *) Data; - msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_CH_REQ\n",Header->inst); - rrc_init_ch_req(Header->inst,p); - break; - } - - case RRCI_INIT_MR_REQ: { - rrci_init_mr_req_t *p = (rrci_init_mr_req_t *) Data; - msg( "[RRM]>[RRC][Inst %d]:RRCI_INIT_MR_REQ\n",Header->inst); - rrc_init_mr_req(Header->inst,p); - break; - } - - case RRM_RB_ESTABLISH_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_establish_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_ESTABLISH_REQ, size %d\n",Header->inst,sizeof(rrm_rb_establish_req_t)); - rrc_config_req(Header->inst,(void *)Data,Header->msg_type,Header->Trans_id); - break ; - } - - case RRM_RB_MODIFY_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_modify_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_MODIFY_REQ\n",Header->inst); - rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); - } - - case RRM_RB_RELEASE_REQ: { - send_msg((void *)&S_rrc,msg_rrc_rb_release_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_RB_RELEASE_REQ\n",Header->inst); - rrc_config_req(Header->inst,Data,Header->msg_type,Header->Trans_id); - } - - case RRCI_CX_ESTABLISH_RESP: { - rrci_cx_establish_resp_t *p = (rrci_cx_establish_resp_t *) Data; - unsigned char i, CH_index = 0; - msg( "[RRCI]>[RRC][Inst %d]:RRCI_CX_ESTABLISH_RESP\n",Header->inst); - - for(i=0; iinst-NB_CH_INST].Info[i].CH_mac_id,&p->L2_id,sizeof(L2_ID))) { - CH_index=i; - break; - } - - if(i==NB_SIG_CNX_UE) { - msg("[RRC] FATAL: CH_INDEX NOT FOUND\n"); - return; - } - - UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr_type=p->L3_info_t; - - if(p->L3_info_t == IPv4_ADDR) { - memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,4); - } else { - memcpy(&UE_rrc_inst[Header->inst-NB_CH_INST].Srb2[CH_index].Srb_info.IP_addr,p->L3_info,16); - } - } - break ; - - case RRM_SENSING_MEAS_REQ: { - // rrm_sensing_meas_req_t *p = (rrm_sensing_meas_req_t *) sock_msg ; - send_msg((void *)&S_rrc,msg_rrc_sensing_meas_resp(Header->inst,Header->Trans_id)); - msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_REQ\n",Header->inst); - // rrc_meas_req(header->inst,p,RRC_MEAS_ADD); - } - break ; - - case RRM_SENSING_MEAS_RESP: { - msg( "[RRM]>[RRC][Inst %d]:RRM_SENSING_MEAS_RESP\n",Header->inst); - //rrm_rrc_meas_resp(header->inst,header->Trans_id); - } - break ; - - case RRM_SCAN_ORD: - msg( "[RRM]>[RRC][Inst %d]:RRM_SCAN_ORD\n",Header->inst); - //memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); - //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air - break; - - case RRM_INIT_SCAN_REQ: - msg( "[RRM]>[RRC][Inst %d]:RRM_INIT_SCAN_REQ\n",Header->inst); - memcpy(&CH_rrc_inst[0].Rrm_init_scan_req,(rrm_init_scan_req_t *) Data,sizeof(rrm_init_scan_req_t)); - CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air - break; - - case RRM_END_SCAN_REQ: - msg( "[RRM]>[RRC][Inst %d]:RRM_END_SCAN_REQ\n",Header->inst); - memcpy(&Mac_id.L2_id[0],Data,sizeof(L2_ID)); - unsigned char UE_index=Mac_id.L2_id[0]-NB_CH_MAX+1; - UE_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload[0]=100; - msg("SRB_ID %d\n",CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id); - Mac_rlc_xface->rrc_rlc_data_req(0,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Srb_id,0,0,1,CH_rrc_inst[0].Srb2[UE_index].Srb_info.Tx_buffer.Payload); - //CH_rrc_inst[0].Last_scan_req=Rrc_xface->Frame_index; - ///send over air - break; - - default : - msg("[L3_xface]WARNING: msg unknown %d\n",Header->msg_type) ; - } - } -} diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 0905f6d7de..eb43eeb5f2 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -35,6 +35,8 @@ #include "pdcp.h" #include "msc.h" #include "common/ran_context.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "intertask_interface.h" @@ -43,6 +45,174 @@ extern RAN_CONTEXT_t RC; +int generate_pdcch_ConfigSIB1(NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1, + long ssbSubcarrierSpacing, + long subCarrierSpacingCommon, + channel_bandwidth_t min_channel_bw) { + + nr_ssb_and_cset_mux_pattern_type_t mux_pattern = 0; + + switch (ssbSubcarrierSpacing) { + + case NR_SubcarrierSpacing_kHz15: + if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_1_NUM_INDEXES; + mux_pattern = table_38213_13_1_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_2_NUM_INDEXES; + mux_pattern = table_38213_13_2_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else { + AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); + } + break; + + case NR_SubcarrierSpacing_kHz30: + if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) { + + if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_3_NUM_INDEXES; + mux_pattern = table_38213_13_3_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else if (min_channel_bw == bw_40MHz) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_5_NUM_INDEXES; + mux_pattern = table_38213_13_5_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else { + AssertFatal(true,"Invalid min_bandwidth\n"); + } + + } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) { + + if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_4_NUM_INDEXES; + mux_pattern = table_38213_13_4_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else if (min_channel_bw == bw_40MHz) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_6_NUM_INDEXES; + mux_pattern = table_38213_13_6_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else { + AssertFatal(true,"Invalid min_bandwidth\n"); + } + + } else { + AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); + } + break; + + case NR_SubcarrierSpacing_kHz120: + if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_7_NUM_INDEXES; + mux_pattern = table_38213_13_7_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_8_NUM_INDEXES; + mux_pattern = table_38213_13_8_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else { + AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); + } + break; + + case NR_SubcarrierSpacing_kHz240: + if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_9_NUM_INDEXES; + mux_pattern = table_38213_13_9_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) { + pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_10_NUM_INDEXES; + mux_pattern = table_38213_13_10_c1[pdcch_ConfigSIB1->controlResourceSetZero]; + } else { + AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); + } + break; + + default: + AssertFatal(true,"Invalid ssbSubcarrierSpacing\n"); + break; + } + + + frequency_range_t frequency_range = FR1; + if(ssbSubcarrierSpacing>=60) { + frequency_range = FR2; + } + + pdcch_ConfigSIB1->searchSpaceZero = 0; + if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR1){ + pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_11_NUM_INDEXES; + } + if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR2){ + pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_12_NUM_INDEXES; + } + + return 0; +} + +int +nr_rrc_mac_remove_ue(module_id_t mod_idP, + rnti_t rntiP){ + // todo + return 0; +} + +//------------------------------------------------------------------------------ +uint8_t +nr_rrc_data_req( + const protocol_ctxt_t *const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t *const buffer_pP, + const pdcp_transmission_mode_t modeP +) +//------------------------------------------------------------------------------ +{ + if(sdu_sizeP == 255) { + LOG_I(RRC,"sdu_sizeP == 255"); + return FALSE; + } + + MSC_LOG_TX_MESSAGE( + ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE, + ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE, + buffer_pP, + sdu_sizeP, + MSC_AS_TIME_FMT"RRC_DCCH_DATA_REQ UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->rnti, + muiP, + sdu_sizeP); + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + message_buffer = itti_malloc ( + ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + sdu_sizeP); + memcpy (message_buffer, buffer_pP, sdu_sizeP); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ); + RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; + RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; + RRC_DCCH_DATA_REQ (message_p).muip = muiP; + RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; + RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; + //memcpy (RRC_DCCH_DATA_REQ (message_p).sdu_p, buffer_pP, sdu_sizeP); + RRC_DCCH_DATA_REQ (message_p).mode = modeP; + RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; + itti_send_msg_to_task ( + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + ctxt_pP->instance, + message_p); + LOG_I(RRC,"sent RRC_DCCH_DATA_REQ to TASK_PDCP_ENB\n"); + + /* Hack: only trigger PDCP if in CU, otherwise it is triggered by RU threads + * Ideally, PDCP would not neet to be triggered like this but react to ITTI + * messages automatically */ + if (ctxt_pP->enb_flag && NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) + pdcp_run(ctxt_pP); + + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. +} + int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, const int CC_id, const frame_t frameP, @@ -58,36 +228,55 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); #endif - gNB_RRC_INST *rrc; - rrc_gNB_carrier_data_t *carrier; - NR_BCCH_BCH_Message_t *mib; - NR_SRB_INFO * srb_info; - char payload_size, *payload_pP; - - rrc = RC.nrrrc[Mod_idP]; - carrier = &rrc->carrier; - mib = &carrier->mib; - srb_info = &carrier->Srb0; + rrc_gNB_carrier_data_t *carrier; + NR_BCCH_BCH_Message_t *mib; + NR_SRB_INFO *srb_info; + char payload_size, *payload_pP; - /* MIBCH */ - if( (Srb_id & RAB_OFFSET ) == MIBCH) { - mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2; - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message, - NULL, - (void *)mib, - carrier->MIB, - 24); - LOG_D(NR_RRC,"Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n",frameP,sfn_msb,carrier->MIB,enc_rval.encoded); - buffer_pP[0]=carrier->MIB[0]; - buffer_pP[1]=carrier->MIB[1]; - buffer_pP[2]=carrier->MIB[2]; - LOG_D(NR_RRC,"MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n",buffer_pP[0],buffer_pP[1],buffer_pP[2]); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return(3); - } + carrier = &RC.nrrrc[Mod_idP]->carrier; + mib = &carrier->mib; + srb_info = &carrier->Srb0; + + /* MIBCH */ + if ((Srb_id & RAB_OFFSET) == MIBCH) { + + // Currently we are getting the pdcch_ConfigSIB1 from the configuration file. + // Uncomment this function for a dynamic pdcch_ConfigSIB1. + //channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1 + //generate_pdcch_ConfigSIB1(carrier->pdcch_ConfigSIB1, + // *carrier->servingcellconfigcommon->ssbSubcarrierSpacing, + // carrier->mib.message.choice.mib->subCarrierSpacingCommon, + // min_channel_bw); + + mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = carrier->pdcch_ConfigSIB1->controlResourceSetZero; + mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = carrier->pdcch_ConfigSIB1->searchSpaceZero; + + mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2; + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message, + NULL, + (void *) mib, + carrier->MIB, + 24); + LOG_D(NR_RRC, "Encoded MIB for frame %d sfn_msb %d (%p), bits %lu\n", frameP, sfn_msb, carrier->MIB, + enc_rval.encoded); + buffer_pP[0] = carrier->MIB[0]; + buffer_pP[1] = carrier->MIB[1]; + buffer_pP[2] = carrier->MIB[2]; + LOG_D(NR_RRC, "MIB PDU buffer_pP[0]=%x , buffer_pP[1]=%x, buffer_pP[2]=%x\n", buffer_pP[0], buffer_pP[1], + buffer_pP[2]); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return (3); + } /* TODO BCCH SIB1 SIBs */ + if ((Srb_id & RAB_OFFSET ) == BCCH) { + memcpy(&buffer_pP[0], + RC.nrrrc[Mod_idP]->carrier.SIB1, + RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1); + + return RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1; + } /* CCCH */ if( (Srb_id & RAB_OFFSET ) == CCCH) { @@ -114,4 +303,4 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, return(0); -} \ No newline at end of file +} diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index c00b57d7aa..82855365c8 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -41,8 +41,37 @@ #include #include "asn1_msg.h" +#include "../nr_rrc_proto.h" #include "RRC/NR/nr_rrc_extern.h" -#if defined(NR_Rel15) +#include "NR_DL-CCCH-Message.h" +#include "NR_UL-CCCH-Message.h" +#include "NR_DL-DCCH-Message.h" +#include "NR_RRCReject.h" +#include "NR_RejectWaitTime.h" +#include "NR_RRCSetup.h" +#include "NR_RRCSetup-IEs.h" +#include "NR_SRB-ToAddModList.h" +#include "NR_CellGroupConfig.h" +#include "NR_RLC-BearerConfig.h" +#include "NR_RLC-Config.h" +#include "NR_LogicalChannelConfig.h" +#include "NR_PDCP-Config.h" +#include "NR_MAC-CellGroupConfig.h" +#include "NR_SecurityModeCommand.h" +#include "NR_CipheringAlgorithm.h" +#include "NR_RRCReconfiguration-IEs.h" +#include "NR_DRB-ToAddMod.h" +#include "NR_DRB-ToAddModList.h" +#include "NR_SecurityConfig.h" +#include "NR_RRCReconfiguration-v1530-IEs.h" +#include "NR_UL-DCCH-Message.h" +#include "NR_SDAP-Config.h" +#include "NR_RRCReconfigurationComplete.h" +#include "NR_RRCReconfigurationComplete-IEs.h" +#include "NR_DLInformationTransfer.h" +#include "NR_RRCReestablishmentRequest.h" +#include "PHY/defs_nr_common.h" +#if defined(NR_Rel16) #include "NR_SCS-SpecificCarrier.h" #include "NR_TDD-UL-DL-ConfigCommon.h" #include "NR_FrequencyInfoUL.h" @@ -200,8 +229,19 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { mib->message.choice.mib->spare.bits_unused = 7; // This makes a spare of 1 bits mib->message.choice.mib->ssb_SubcarrierOffset = (carrier->ssb_SubcarrierOffset)&15; - mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; - mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero; + + /* + * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables + * the reverse allocation is in nr_ue_decode_mib() + */ + if(rrc->carrier.pdcch_ConfigSIB1) { + mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = rrc->carrier.pdcch_ConfigSIB1->controlResourceSetZero; + mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = rrc->carrier.pdcch_ConfigSIB1->searchSpaceZero; + } else { + mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero; + mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero; + } + AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n"); switch (*scc->ssbSubcarrierSpacing) { case NR_SubcarrierSpacing_kHz15: @@ -265,86 +305,348 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration ) { asn_enc_rval_t enc_rval; - NR_BCCH_DL_SCH_Message_t *sib1_message ; - struct NR_SIB1 *sib1 ; - int i; - struct NR_PLMN_IdentityInfo nr_plmn_info; // TODO : Add support for more than one PLMN - //int num_plmn = configuration->num_plmn; - int num_plmn = 1; + int num_plmn = 1; // int num_plmn = configuration->num_plmn; struct NR_PLMN_Identity nr_plmn[num_plmn]; NR_MCC_MNC_Digit_t nr_mcc_digit[num_plmn][3]; NR_MCC_MNC_Digit_t nr_mnc_digit[num_plmn][3]; - // struct NR_UAC_BarringInfoSet nr_uac_BarringInfoSet; - sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); - memset(sib1_message,0,sizeof(NR_BCCH_DL_SCH_Message_t)); + memset(nr_plmn,0,sizeof(nr_plmn)); + memset(nr_mcc_digit,0,sizeof(nr_mcc_digit)); + memset(nr_mnc_digit,0,sizeof(nr_mnc_digit)); + + NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); carrier->siblock1 = sib1_message; sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; sib1_message->message.choice.c1 = CALLOC(1,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); - memset(sib1_message->message.choice.c1,0,sizeof(struct NR_BCCH_DL_SCH_MessageType__c1)); sib1_message->message.choice.c1->present = NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; sib1_message->message.choice.c1->choice.systemInformationBlockType1 = CALLOC(1,sizeof(struct NR_SIB1)); - sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; - memset(sib1,0,sizeof(struct NR_SIB1)); - sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo)); - memset(sib1->cellSelectionInfo,0,sizeof(struct NR_SIB1__cellSelectionInfo)); - sib1->cellSelectionInfo->q_RxLevMin = -50; - memset(&nr_plmn_info.plmn_IdentityList,0,sizeof(struct NR_PLMN_IdentityInfo__plmn_IdentityList)); - asn_set_empty(&nr_plmn_info.plmn_IdentityList.list); - memset(&nr_plmn_info,0,sizeof(struct NR_PLMN_IdentityInfo)); - memset(nr_plmn,0,num_plmn*sizeof(struct NR_PLMN_Identity)); - for (i = 0; i < num_plmn; ++i) { + struct NR_SIB1 *sib1 = sib1_message->message.choice.c1->choice.systemInformationBlockType1; + + // cellSelectionInfo + sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo)); + sib1->cellSelectionInfo->q_RxLevMin = -50; + + // cellAccessRelatedInfo + struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo)); + asn_set_empty(&nr_plmn_info->plmn_IdentityList.list); + for (int i = 0; i < num_plmn; ++i) { nr_mcc_digit[i][0] = (configuration->mcc[i]/100)%10; nr_mcc_digit[i][1] = (configuration->mcc[i]/10)%10; nr_mcc_digit[i][2] = (configuration->mcc[i])%10; nr_plmn[i].mcc = CALLOC(1,sizeof(struct NR_MCC)); - memset(nr_plmn[i].mcc,0,sizeof(struct NR_MCC)); asn_set_empty(&nr_plmn[i].mcc->list); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][0]); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][1]); ASN_SEQUENCE_ADD(&nr_plmn[i].mcc->list, &nr_mcc_digit[i][2]); - nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10; + if(configuration->mnc_digit_length[i] == 3) nr_mnc_digit[i][0] = (configuration->mnc[i]/100)%10; nr_mnc_digit[i][1] = (configuration->mnc[i]/10)%10; nr_mnc_digit[i][2] = (configuration->mnc[i])%10; - memset(&nr_plmn[i].mnc,0,sizeof(NR_MNC_t)); nr_plmn[i].mnc.list.size=0; nr_plmn[i].mnc.list.count=0; - ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][0]); + if(configuration->mnc_digit_length[i] == 3) ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][0]); ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][1]); ASN_SEQUENCE_ADD(&nr_plmn[i].mnc.list, &nr_mnc_digit[i][2]); - ASN_SEQUENCE_ADD(&nr_plmn_info.plmn_IdentityList.list, &nr_plmn[i]); + ASN_SEQUENCE_ADD(&nr_plmn_info->plmn_IdentityList.list, &nr_plmn[i]); }//end plmn loop - nr_plmn_info.cellIdentity.buf = MALLOC(8); - memset(nr_plmn_info.cellIdentity.buf,0,8); - nr_plmn_info.cellIdentity.buf[0]= (configuration->cell_identity >> 20) & 0xff; - nr_plmn_info.cellIdentity.buf[1]= (configuration->cell_identity >> 12) & 0xff; - nr_plmn_info.cellIdentity.buf[2]= (configuration->cell_identity >> 4) & 0xff; - nr_plmn_info.cellIdentity.buf[3]= (configuration->cell_identity << 4) & 0xff; - nr_plmn_info.cellIdentity.size= 4; - nr_plmn_info.cellIdentity.bits_unused= 4; - nr_plmn_info.cellReservedForOperatorUse = 0; - memset(&sib1->cellAccessRelatedInfo,0,sizeof(NR_CellAccessRelatedInfo_t)); - ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, &nr_plmn_info); -#if 0 - sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo)); - memset(sib1->uac_BarringInfo, 0, sizeof(struct NR_SIB1__uac_BarringInfo)); - nr_uac_BarringInfoSet.uac_BarringFactor = NR_UAC_BarringInfoSet__uac_BarringFactor_p95; - nr_uac_BarringInfoSet.uac_BarringTime = NR_UAC_BarringInfoSet__uac_BarringTime_s4; - nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.buf = MALLOC(1); - memset(nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.buf,0,1); - nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.size = 1; - nr_uac_BarringInfoSet.uac_BarringForAccessIdentity.bits_unused = 1; - ASN_SEQUENCE_ADD(&sib1->uac_BarringInfo->uac_BarringInfoSetList, &nr_uac_BarringInfoSet); -#endif - //encode SIB1 to data + nr_plmn_info->cellIdentity.buf = CALLOC(1,5); + nr_plmn_info->cellIdentity.buf[0]= (configuration->cell_identity >> 28) & 0xff; + nr_plmn_info->cellIdentity.buf[1]= (configuration->cell_identity >> 20) & 0xff; + nr_plmn_info->cellIdentity.buf[2]= (configuration->cell_identity >> 12) & 0xff; + nr_plmn_info->cellIdentity.buf[3]= (configuration->cell_identity >> 4) & 0xff; + nr_plmn_info->cellIdentity.buf[4]= (configuration->cell_identity << 4) & 0xff; + nr_plmn_info->cellIdentity.size= 5; + nr_plmn_info->cellIdentity.bits_unused= 4; + nr_plmn_info->cellReservedForOperatorUse = NR_PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; + + nr_plmn_info->trackingAreaCode = CALLOC(1,sizeof(NR_TrackingAreaCode_t)); + nr_plmn_info->trackingAreaCode->buf = CALLOC(1,3); + nr_plmn_info->trackingAreaCode->buf[0] = ( ((uint32_t)configuration->tac) >> 16) & 0xff; + nr_plmn_info->trackingAreaCode->buf[1] = ( ((uint32_t)configuration->tac) >> 8) & 0xff; + nr_plmn_info->trackingAreaCode->buf[2] = ( ((uint32_t)configuration->tac) >> 0) & 0xff; + nr_plmn_info->trackingAreaCode->size = 3; + nr_plmn_info->trackingAreaCode->bits_unused = 0; + + ASN_SEQUENCE_ADD(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list, nr_plmn_info); + + // connEstFailureControl + // TODO: add connEstFailureControl + + //si-SchedulingInfo + /*sib1->si_SchedulingInfo = CALLOC(1,sizeof(struct NR_SI_SchedulingInfo)); + asn_set_empty(&sib1->si_SchedulingInfo->schedulingInfoList.list); + sib1->si_SchedulingInfo->si_WindowLength = NR_SI_SchedulingInfo__si_WindowLength_s40; + struct NR_SchedulingInfo *schedulingInfo = CALLOC(1,sizeof(struct NR_SchedulingInfo)); + schedulingInfo->si_BroadcastStatus = NR_SchedulingInfo__si_BroadcastStatus_broadcasting; + schedulingInfo->si_Periodicity = NR_SchedulingInfo__si_Periodicity_rf8; + asn_set_empty(&schedulingInfo->sib_MappingInfo.list); + + NR_SIB_TypeInfo_t *sib_type3 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type3->type = NR_SIB_TypeInfo__type_sibType3; + sib_type3->valueTag = CALLOC(1,sizeof(sib_type3->valueTag)); + ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type3); + + NR_SIB_TypeInfo_t *sib_type5 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type5->type = NR_SIB_TypeInfo__type_sibType5; + sib_type5->valueTag = CALLOC(1,sizeof(sib_type5->valueTag)); + ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type5); + + NR_SIB_TypeInfo_t *sib_type4 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type4->type = NR_SIB_TypeInfo__type_sibType4; + sib_type4->valueTag = CALLOC(1,sizeof(sib_type4->valueTag)); + ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type4); + + NR_SIB_TypeInfo_t *sib_type2 = CALLOC(1,sizeof(e_NR_SIB_TypeInfo__type)); + sib_type2->type = NR_SIB_TypeInfo__type_sibType2; + sib_type2->valueTag = CALLOC(1,sizeof(sib_type2->valueTag)); + ASN_SEQUENCE_ADD(&schedulingInfo->sib_MappingInfo.list,sib_type2); + + ASN_SEQUENCE_ADD(&sib1->si_SchedulingInfo->schedulingInfoList.list,schedulingInfo);*/ + + // servingCellConfigCommon + sib1->servingCellConfigCommon = CALLOC(1,sizeof(struct NR_ServingCellConfigCommonSIB)); + + asn_set_empty(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list); + asn_set_empty(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list); + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth; + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing; + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters.cyclicPrefix = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix; + for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count; i++) { + struct NR_NR_MultiBandInfo *nrMultiBandInfo = CALLOC(1,sizeof(struct NR_NR_MultiBandInfo)); + nrMultiBandInfo->freqBandIndicatorNR = configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[i]; + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list,nrMultiBandInfo); + } + sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; + for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) { + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list,configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[i]); + } + + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon; + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList)); + asn_set_empty(&sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list); + + NR_SearchSpace_t *ss1 = calloc(1,sizeof(*ss1)); + ss1->searchSpaceId = 1; + ss1->controlResourceSetId=calloc(1,sizeof(*ss1->controlResourceSetId)); + *ss1->controlResourceSetId=0; + ss1->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss1->monitoringSlotPeriodicityAndOffset)); + ss1->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; + ss1->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss1->monitoringSymbolsWithinSlot)); + ss1->monitoringSymbolsWithinSlot->buf = calloc(1,2); + // should be '1100 0000 0000 00'B (LSB first!), first two symols in slot, adjust if needed + ss1->monitoringSymbolsWithinSlot->buf[1] = 0; + ss1->monitoringSymbolsWithinSlot->buf[0] = (1<<7); + ss1->monitoringSymbolsWithinSlot->size = 2; + ss1->monitoringSymbolsWithinSlot->bits_unused = 2; + ss1->nrofCandidates = calloc(1,sizeof(*ss1->nrofCandidates)); + ss1->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + ss1->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + ss1->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + ss1->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; + ss1->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + ss1->searchSpaceType = calloc(1,sizeof(*ss1->searchSpaceType)); + ss1->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; + ss1->searchSpaceType->choice.common=calloc(1,sizeof(*ss1->searchSpaceType->choice.common)); + ss1->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss1->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss1); + + NR_SearchSpace_t *ss5 = calloc(1,sizeof(*ss5)); + ss5->searchSpaceId = 5; + ss5->controlResourceSetId=calloc(1,sizeof(*ss5->controlResourceSetId)); + *ss5->controlResourceSetId=0; + ss5->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss5->monitoringSlotPeriodicityAndOffset)); + ss5->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5; + ss5->monitoringSlotPeriodicityAndOffset->choice.sl5 = 0; + ss5->duration = calloc(1,sizeof(*ss5->duration)); + *ss5->duration = 2; + ss5->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss5->monitoringSymbolsWithinSlot)); + ss5->monitoringSymbolsWithinSlot->buf = calloc(1,2); + // should be '1100 0000 0000 00'B (LSB first!), first two symols in slot, adjust if needed + ss5->monitoringSymbolsWithinSlot->buf[1] = 0; + ss5->monitoringSymbolsWithinSlot->buf[0] = (1<<7); + ss5->monitoringSymbolsWithinSlot->size = 2; + ss5->monitoringSymbolsWithinSlot->bits_unused = 2; + ss5->nrofCandidates = calloc(1,sizeof(*ss5->nrofCandidates)); + ss5->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + ss5->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + ss5->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4; + ss5->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n2; + ss5->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n1; + ss5->searchSpaceType = calloc(1,sizeof(*ss5->searchSpaceType)); + ss5->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; + ss5->searchSpaceType->choice.common=calloc(1,sizeof(*ss5->searchSpaceType->choice.common)); + ss5->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss5->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss5); + + NR_SearchSpace_t *ss7 = calloc(1,sizeof(*ss7)); + ss7->searchSpaceId = 7; + ss7->controlResourceSetId=calloc(1,sizeof(*ss7->controlResourceSetId)); + *ss7->controlResourceSetId=0; + ss7->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss7->monitoringSlotPeriodicityAndOffset)); + ss7->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; + ss7->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss7->monitoringSymbolsWithinSlot)); + ss7->monitoringSymbolsWithinSlot->buf = calloc(1,2); + // should be '1100 0000 0000 00'B (LSB first!), first two symols in slot, adjust if needed + ss7->monitoringSymbolsWithinSlot->buf[1] = 0; + ss7->monitoringSymbolsWithinSlot->buf[0] = (1<<7); + ss7->monitoringSymbolsWithinSlot->size = 2; + ss7->monitoringSymbolsWithinSlot->bits_unused = 2; + ss7->nrofCandidates = calloc(1,sizeof(*ss7->nrofCandidates)); + ss7->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + ss7->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + ss7->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4; + ss7->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n2; + ss7->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n1; + ss7->searchSpaceType = calloc(1,sizeof(*ss7->searchSpaceType)); + ss7->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; + ss7->searchSpaceType->choice.common=calloc(1,sizeof(*ss7->searchSpaceType->choice.common)); + ss7->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss7->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss7); + + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = calloc(1,sizeof(NR_SearchSpaceId_t)); + *sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = 0; + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation = calloc(1,sizeof(NR_SearchSpaceId_t)); + *sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation = 7; + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->pagingSearchSpace = calloc(1,sizeof(NR_SearchSpaceId_t)); + *sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->pagingSearchSpace = 5; + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->ra_SearchSpace = calloc(1,sizeof(NR_SearchSpaceId_t)); + *sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->ra_SearchSpace = 1; + + sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon = configuration->scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon; + sib1->servingCellConfigCommon->downlinkConfigCommon.bcch_Config.modificationPeriodCoeff = NR_BCCH_Config__modificationPeriodCoeff_n2; + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle = NR_PagingCycle_rf256; + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present = NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT; + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.choice.quarterT = 1; + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns = NR_PCCH_Config__ns_one; + + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO = calloc(1,sizeof(struct NR_PCCH_Config__firstPDCCH_MonitoringOccasionOfPO)); + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO->present = NR_PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT; + + sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO->choice.sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT = CALLOC(1,sizeof(struct NR_PCCH_Config__firstPDCCH_MonitoringOccasionOfPO__sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT)); + asn_set_empty(&sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO->choice.sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT->list); + + long *sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT = calloc(1,sizeof(long)); + *sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT = 0; + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.firstPDCCH_MonitoringOccasionOfPO->choice.sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT->list,sCS120KHZoneT_SCS60KHZhalfT_SCS30KHZquarterT_SCS15KHZoneEighthT); + + sib1->servingCellConfigCommon->uplinkConfigCommon = CALLOC(1,sizeof(struct NR_UplinkConfigCommonSIB)); + asn_set_empty(&sib1->servingCellConfigCommon->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list); + for(int i = 0; i< configuration->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.count; i++) { + ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list,configuration->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[i]); + } + + sib1->servingCellConfigCommon->uplinkConfigCommon->frequencyInfoUL.p_Max = CALLOC(1,sizeof(NR_P_Max_t)); + *sib1->servingCellConfigCommon->uplinkConfigCommon->frequencyInfoUL.p_Max = 23; + + sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.genericParameters = configuration->scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon; + + sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; + sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->groupHoppingEnabledTransformPrecoding = null; + + sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon = configuration->scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; + + sib1->servingCellConfigCommon->uplinkConfigCommon->timeAlignmentTimerCommon = NR_TimeAlignmentTimer_infinity; + + sib1->servingCellConfigCommon->n_TimingAdvanceOffset = configuration->scc->n_TimingAdvanceOffset; + + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.buf = calloc(1, sizeof(uint8_t)); + uint8_t bitmap8,temp_bitmap=0; + switch (configuration->scc->ssb_PositionsInBurst->present) { + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.shortBitmap; + break; + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup = configuration->scc->ssb_PositionsInBurst->choice.mediumBitmap; + break; + /* + groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1. + The first/leftmost bit corresponds to the SS/PBCH index 0-7, the second bit corresponds to SS/PBCH block 8-15, and so on. + Value 0 in the bitmap indicates that the SSBs according to inOneGroup are absent. Value 1 indicates that the SS/PBCH blocks are transmitted in accordance with inOneGroup. + inOneGroup: When maximum number of SS/PBCH blocks per half frame equals to 64 as defined in TS 38.213 [13], clause 4.1, all 8 bit are valid; + The first/ leftmost bit corresponds to the first SS/PBCH block index in the group (i.e., to SSB index 0, 8, and so on); the second bit corresponds to the second SS/PBCH block index in the group + (i.e., to SSB index 1, 9, and so on), and so on. Value 0 in the bitmap indicates that the corresponding SS/PBCH block is not transmitted while value 1 indicates that the corresponding SS/PBCH block is transmitted. + */ + case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.size = 1; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.bits_unused = 0; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence = calloc(1, sizeof(BIT_STRING_t)); + memset(sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence, 0, sizeof(BIT_STRING_t)); + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->size = 1; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->bits_unused = 0; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->buf = calloc(1, sizeof(uint8_t)); + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->buf[0] = 0; + for (int i=0; i<8; i++){ + bitmap8 = configuration->scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]; + if (bitmap8!=0){ + if(temp_bitmap==0) + temp_bitmap = bitmap8; + else + AssertFatal(temp_bitmap==bitmap8,"For longBitmap the groups of 8 SSBs containing at least 1 transmitted SSB should be all the same\n"); + + sib1->servingCellConfigCommon->ssb_PositionsInBurst.inOneGroup.buf[0] = bitmap8; + sib1->servingCellConfigCommon->ssb_PositionsInBurst.groupPresence->buf[0] |= 1<<(7-i); + } + } + break; + default: + AssertFatal(false,"ssb_PositionsInBurst not present\n"); + break; + } + + sib1->servingCellConfigCommon->ssb_PeriodicityServingCell = *configuration->scc->ssb_periodicityServingCell; + sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); + sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = configuration->scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; + sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->pattern1 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern1; + sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon->pattern2 = configuration->scc->tdd_UL_DL_ConfigurationCommon->pattern2; + sib1->servingCellConfigCommon->ss_PBCH_BlockPower = configuration->scc->ss_PBCH_BlockPower; + + // ims-EmergencySupport + // TODO: add ims-EmergencySupport + + // eCallOverIMS-Support + // TODO: add eCallOverIMS-Support + + // ue-TimersAndConstants + sib1->ue_TimersAndConstants = CALLOC(1,sizeof(struct NR_UE_TimersAndConstants)); + sib1->ue_TimersAndConstants->t300 = NR_UE_TimersAndConstants__t300_ms400; + sib1->ue_TimersAndConstants->t301 = NR_UE_TimersAndConstants__t301_ms400; + sib1->ue_TimersAndConstants->t310 = NR_UE_TimersAndConstants__t310_ms2000; + sib1->ue_TimersAndConstants->n310 = NR_UE_TimersAndConstants__n310_n10; + sib1->ue_TimersAndConstants->t311 = NR_UE_TimersAndConstants__t311_ms3000; + sib1->ue_TimersAndConstants->n311 = NR_UE_TimersAndConstants__n311_n1; + sib1->ue_TimersAndConstants->t319 = NR_UE_TimersAndConstants__t319_ms400; + + // uac-BarringInfo + /*sib1->uac_BarringInfo = CALLOC(1, sizeof(struct NR_SIB1__uac_BarringInfo)); + NR_UAC_BarringInfoSet_t *nr_uac_BarringInfoSet = CALLOC(1, sizeof(NR_UAC_BarringInfoSet_t)); + asn_set_empty(&sib1->uac_BarringInfo->uac_BarringInfoSetList); + nr_uac_BarringInfoSet->uac_BarringFactor = NR_UAC_BarringInfoSet__uac_BarringFactor_p95; + nr_uac_BarringInfoSet->uac_BarringTime = NR_UAC_BarringInfoSet__uac_BarringTime_s4; + nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.buf = CALLOC(1, 1); + nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.size = 1; + nr_uac_BarringInfoSet->uac_BarringForAccessIdentity.bits_unused = 1; + ASN_SEQUENCE_ADD(&sib1->uac_BarringInfo->uac_BarringInfoSetList, nr_uac_BarringInfoSet);*/ + + // useFullResumeID + // TODO: add useFullResumeID + + // lateNonCriticalExtension + // TODO: add lateNonCriticalExtension + + // nonCriticalExtension + // TODO: add nonCriticalExtension + + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1_message->message.choice.c1->choice.systemInformationBlockType1); + + if(carrier->SIB1 == NULL) carrier->SIB1=(uint8_t *) malloc16(NR_MAX_SIB_LENGTH/8); enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_DL_SCH_Message, NULL, (void *)sib1_message, carrier->SIB1, - 100); + NR_MAX_SIB_LENGTH/8); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); @@ -578,3 +880,854 @@ void do_SpCellConfig(gNB_RRC_INST *rrc, spconfig->reconfigurationWithSync = CALLOC(1,sizeof(struct NR_ReconfigurationWithSync)); } +//------------------------------------------------------------------------------ +uint8_t do_RRCReject(uint8_t Mod_id, + uint8_t *const buffer) +//------------------------------------------------------------------------------ +{ + asn_enc_rval_t enc_rval;; + NR_DL_CCCH_Message_t dl_ccch_msg; + NR_RRCReject_t *rrcReject; + NR_RejectWaitTime_t waitTime = 1; + + memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t)); + dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1; + dl_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_CCCH_MessageType__c1)); + dl_ccch_msg.message.choice.c1->present = NR_RRCReject__criticalExtensions_PR_rrcReject; + + dl_ccch_msg.message.choice.c1->choice.rrcReject = CALLOC(1,sizeof(NR_RRCReject_t)); + rrcReject = dl_ccch_msg.message.choice.c1->choice.rrcReject; + + rrcReject->criticalExtensions.choice.rrcReject = CALLOC(1, sizeof(struct NR_RRCReject_IEs)); + rrcReject->criticalExtensions.choice.rrcReject->waitTime = CALLOC(1, sizeof(NR_RejectWaitTime_t)); + + rrcReject->criticalExtensions.present = NR_RRCReject__criticalExtensions_PR_rrcReject; + rrcReject->criticalExtensions.choice.rrcReject->waitTime = &waitTime; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_CCCH_Message, + NULL, + (void *)&dl_ccch_msg, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_D(NR_RRC,"RRCReject Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} + +//------------------------------------------------------------------------------ +uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + int CC_id, + uint8_t *const buffer, + const uint8_t transaction_id, + NR_SRB_ToAddModList_t **SRB_configList) +//------------------------------------------------------------------------------ +{ + asn_enc_rval_t enc_rval;; + NR_DL_CCCH_Message_t dl_ccch_msg; + NR_RRCSetup_t *rrcSetup; + NR_RRCSetup_IEs_t *ie; + NR_SRB_ToAddMod_t *SRB1_config = NULL; + NR_PDCP_Config_t *pdcp_Config = NULL; + NR_CellGroupConfig_t *cellGroupConfig = NULL; + NR_RLC_BearerConfig_t *rlc_BearerConfig = NULL; + NR_RLC_Config_t *rlc_Config = NULL; + NR_LogicalChannelConfig_t *logicalChannelConfig = NULL; + NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = NULL; + + char masterCellGroup_buf[1000]; + long *logicalChannelGroup = NULL; + + memset((void *)&dl_ccch_msg, 0, sizeof(NR_DL_CCCH_Message_t)); + dl_ccch_msg.message.present = NR_DL_CCCH_MessageType_PR_c1; + dl_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_CCCH_MessageType__c1)); + dl_ccch_msg.message.choice.c1->present = NR_DL_CCCH_MessageType__c1_PR_rrcSetup; + dl_ccch_msg.message.choice.c1->choice.rrcSetup = calloc(1, sizeof(NR_RRCSetup_t)); + + rrcSetup = dl_ccch_msg.message.choice.c1->choice.rrcSetup; + rrcSetup->criticalExtensions.present = NR_RRCSetup__criticalExtensions_PR_rrcSetup; + rrcSetup->rrc_TransactionIdentifier = transaction_id; + rrcSetup->criticalExtensions.choice.rrcSetup = calloc(1, sizeof(NR_RRCSetup_IEs_t)); + ie = rrcSetup->criticalExtensions.choice.rrcSetup; + + /****************************** radioBearerConfig ******************************/ + /* Configure SRB1 */ + if (*SRB_configList) { + free(*SRB_configList); + } + + *SRB_configList = calloc(1, sizeof(NR_SRB_ToAddModList_t)); + // SRB1 + /* TODO */ + SRB1_config = calloc(1, sizeof(NR_SRB_ToAddMod_t)); + SRB1_config->srb_Identity = 1; + // pdcp_Config->t_Reordering + SRB1_config->pdcp_Config = pdcp_Config; + ie->radioBearerConfig.srb_ToAddModList = *SRB_configList; + ASN_SEQUENCE_ADD(&(*SRB_configList)->list, SRB1_config); + + ie->radioBearerConfig.srb3_ToRelease = NULL; + ie->radioBearerConfig.drb_ToAddModList = NULL; + ie->radioBearerConfig.drb_ToReleaseList = NULL; + ie->radioBearerConfig.securityConfig = NULL; + + /****************************** masterCellGroup ******************************/ + /* TODO */ + cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + cellGroupConfig->cellGroupId = 0; + + /* Rlc Bearer Config */ + /* TS38.331 9.2.1 Default SRB configurations */ + cellGroupConfig->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + rlc_BearerConfig = calloc(1, sizeof(NR_RLC_BearerConfig_t)); + rlc_BearerConfig->logicalChannelIdentity = 1; + rlc_BearerConfig->servedRadioBearer = calloc(1, sizeof(*rlc_BearerConfig->servedRadioBearer)); + rlc_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity; + rlc_BearerConfig->servedRadioBearer->choice.srb_Identity = 1; + rlc_BearerConfig->reestablishRLC = NULL; + rlc_Config = calloc(1, sizeof(NR_RLC_Config_t)); + rlc_Config->present = NR_RLC_Config_PR_am; + rlc_Config->choice.am = calloc(1, sizeof(*rlc_Config->choice.am)); + rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t)); + *(rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12; + rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms35; + rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms0; + rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t)); + *(rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12; + rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; + rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_infinity; + rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_infinity; + rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t8; + rlc_BearerConfig->rlc_Config = rlc_Config; + logicalChannelConfig = calloc(1, sizeof(NR_LogicalChannelConfig_t)); + logicalChannelConfig->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters)); + logicalChannelConfig->ul_SpecificParameters->priority = 1; + logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + logicalChannelGroup = CALLOC(1, sizeof(long)); + *logicalChannelGroup = 0; + logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup; + rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig; + ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); + + cellGroupConfig->rlc_BearerToReleaseList = NULL; + cellGroupConfig->sCellToAddModList = NULL; + cellGroupConfig->sCellToReleaseList = NULL; + + /* mac CellGroup Config */ + mac_CellGroupConfig = calloc(1, sizeof(NR_MAC_CellGroupConfig_t)); + mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config)); + mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; + mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config)); + mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; + mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); + mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1; + cellGroupConfig->mac_CellGroupConfig = mac_CellGroupConfig; + + // cellGroupConfig.physicalCellGroupConfig; + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + (void *)cellGroupConfig, + masterCellGroup_buf, + 100); + + if(enc_rval.encoded == -1) { + LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + if (OCTET_STRING_fromBuf(&ie->masterCellGroup, masterCellGroup_buf, (enc_rval.encoded+7)/8) == -1) { + LOG_E(NR_RRC, "fatal: OCTET_STRING_fromBuf failed\n"); + return -1; + } + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)&dl_ccch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_CCCH_Message, + NULL, + (void *)&dl_ccch_msg, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_D(NR_RRC,"RRCSetup Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} + +uint8_t do_NR_SecurityModeCommand( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + NR_IntegrityProtAlgorithm_t *integrityProtAlgorithm +) +//------------------------------------------------------------------------------ +{ + NR_DL_DCCH_Message_t dl_dcch_msg; + asn_enc_rval_t enc_rval; + memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1=CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1)); + dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_securityModeCommand; + dl_dcch_msg.message.choice.c1->choice.securityModeCommand = CALLOC(1, sizeof(struct NR_SecurityModeCommand)); + dl_dcch_msg.message.choice.c1->choice.securityModeCommand->rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.present = NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand; + + dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand = + CALLOC(1, sizeof(struct NR_SecurityModeCommand_IEs)); + // the two following information could be based on the mod_id + dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm + = (NR_CipheringAlgorithm_t)cipheringAlgorithm; + dl_dcch_msg.message.choice.c1->choice.securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm + = integrityProtAlgorithm; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_D(NR_RRC,"[gNB %d] securityModeCommand for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + LOG_E(NR_RRC,"[gNB %d] ASN1 : securityModeCommand encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + // rrc_ue_process_ueCapabilityEnquiry(0,1000,&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry,0); + // exit(-1); + return((enc_rval.encoded+7)/8); +} + +/*TODO*/ +//------------------------------------------------------------------------------ +uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, + const uint8_t Transaction_id) +//------------------------------------------------------------------------------ +{ + NR_DL_DCCH_Message_t dl_dcch_msg; + NR_UE_CapabilityRAT_Request_t *ue_capabilityrat_request; + + asn_enc_rval_t enc_rval; + memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1)); + dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry; + dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry = CALLOC(1,sizeof(struct NR_UECapabilityEnquiry)); + dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.present = NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry; + dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry = CALLOC(1,sizeof(struct NR_UECapabilityEnquiry_IEs)); + ue_capabilityrat_request = CALLOC(1,sizeof(NR_UE_CapabilityRAT_Request_t)); + memset(ue_capabilityrat_request,0,sizeof(NR_UE_CapabilityRAT_Request_t)); + ue_capabilityrat_request->rat_Type = NR_RAT_Type_nr; + + ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1->choice.ueCapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list, + ue_capabilityrat_request); + + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_D(NR_RRC,"[gNB %d] NR UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); + + if (enc_rval.encoded==-1) { + LOG_E(NR_RRC,"[gNB %d] ASN1 : NR UECapabilityRequest encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + + +uint8_t do_NR_RRCRelease(uint8_t *buffer, + uint8_t Transaction_id) { + asn_enc_rval_t enc_rval; + NR_DL_DCCH_Message_t dl_dcch_msg; + NR_RRCRelease_t *rrcConnectionRelease; + memset(&dl_dcch_msg,0,sizeof(NR_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1=CALLOC(1,sizeof(struct NR_DL_DCCH_MessageType__c1)); + dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcRelease; + dl_dcch_msg.message.choice.c1->choice.rrcRelease = CALLOC(1, sizeof(NR_RRCRelease_t)); + rrcConnectionRelease = dl_dcch_msg.message.choice.c1->choice.rrcRelease; + // RRCConnectionRelease + rrcConnectionRelease->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionRelease->criticalExtensions.present = NR_RRCRelease__criticalExtensions_PR_rrcRelease; + rrcConnectionRelease->criticalExtensions.choice.rrcRelease = CALLOC(1, sizeof(NR_RRCRelease_IEs_t)); + rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq = + CALLOC(1, sizeof(struct NR_RRCRelease_IEs__deprioritisationReq)); + rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_nr; + rrcConnectionRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min10; + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + buffer, + RRC_BUF_SIZE); + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + return((enc_rval.encoded+7)/8); +} + +//------------------------------------------------------------------------------ +uint16_t do_RRCReconfiguration( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + NR_SRB_ToAddModList_t *SRB_configList, + NR_DRB_ToAddModList_t *DRB_configList, + NR_DRB_ToReleaseList_t *DRB_releaseList, + NR_SecurityConfig_t *security_config, + NR_SDAP_Config_t *sdap_config, + NR_MeasConfig_t *meas_config, + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList + *dedicatedNAS_MessageList, + NR_MAC_CellGroupConfig_t *mac_CellGroupConfig) +//------------------------------------------------------------------------------ +{ + NR_DL_DCCH_Message_t dl_dcch_msg; + asn_enc_rval_t enc_rval; + NR_RRCReconfiguration_IEs_t *ie; + + memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1)); + dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration; + + dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration = calloc(1, sizeof(NR_RRCReconfiguration_t)); + dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.present = NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration; + + /******************** Radio Bearer Config ********************/ + /* Configure Security */ + // security_config = CALLOC(1, sizeof(NR_SecurityConfig_t)); + // security_config->securityAlgorithmConfig = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->securityAlgorithmConfig)); + // security_config->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + // security_config->securityAlgorithmConfig->integrityProtAlgorithm = NULL; + // security_config->keyToUse = CALLOC(1, sizeof(*ie->radioBearerConfig->securityConfig->keyToUse)); + // *security_config->keyToUse = NR_SecurityConfig__keyToUse_master; + + ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t)); + ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t)); + ie->radioBearerConfig->srb_ToAddModList = SRB_configList; + ie->radioBearerConfig->drb_ToAddModList = DRB_configList; + ie->radioBearerConfig->securityConfig = security_config; + ie->radioBearerConfig->srb3_ToRelease = NULL; + ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList; + + /******************** Secondary Cell Group ********************/ + // rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier); + // fill_default_secondaryCellGroup( carrier->servingcellconfigcommon, + // ue_context_pP->ue_context.secondaryCellGroup, + // 1, + // 1, + // carrier->pdsch_AntennaPorts, + // carrier->initial_csi_index[gnb_rrc_inst->Nb_ue]); + + /******************** Meas Config ********************/ + // measConfig + ie->measConfig = meas_config; + // lateNonCriticalExtension + ie->lateNonCriticalExtension = NULL; + // nonCriticalExtension + ie->nonCriticalExtension = calloc(1, sizeof(NR_RRCReconfiguration_v1530_IEs_t)); + ie->nonCriticalExtension->dedicatedNAS_MessageList = dedicatedNAS_MessageList; + + dl_dcch_msg.message.choice.c1->choice.rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration = ie; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_D(NR_RRC,"[gNB %d] RRCReconfiguration for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); + + if (enc_rval.encoded == -1) { + LOG_E(NR_RRC,"[gNB %d] ASN1 : RRCReconfiguration encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + + +uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { + asn_enc_rval_t enc_rval; + uint8_t buf[5],buf2=0; + NR_UL_CCCH_Message_t ul_ccch_msg; + NR_RRCSetupRequest_t *rrcSetupRequest; + memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t)); + ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1; + ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1)); + ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest; + ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest = CALLOC(1, sizeof(NR_RRCSetupRequest_t)); + rrcSetupRequest = ul_ccch_msg.message.choice.c1->choice.rrcSetupRequest; + + + if (1) { + rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.size = 5; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.bits_unused = 1; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf = buf; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[0] = rv[0]; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[1] = rv[1]; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[2] = rv[2]; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[3] = rv[3]; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue.buf[4] = rv[4]&0xfe; + } else { + rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.size = 1; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.bits_unused = 0; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf = buf; + rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1.buf[0] = 0x12; + } + + rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; + rrcSetupRequest->rrcSetupRequest.spare.buf = &buf2; + rrcSetupRequest->rrcSetupRequest.spare.size=1; + rrcSetupRequest->rrcSetupRequest.spare.bits_unused = 7; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message, + NULL, + (void *)&ul_ccch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + LOG_D(NR_RRC,"[UE] RRCSetupRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} +//------------------------------------------------------------------------------ +uint8_t +do_NR_RRCReconfigurationComplete( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + const uint8_t Transaction_id +) +//------------------------------------------------------------------------------ +{ + asn_enc_rval_t enc_rval; + NR_UL_DCCH_Message_t ul_dcch_msg; + NR_RRCReconfigurationComplete_t *rrcReconfigurationComplete; + memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete; + ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete = CALLOC(1, sizeof(NR_RRCReconfigurationComplete_t)); + rrcReconfigurationComplete = ul_dcch_msg.message.choice.c1->choice.rrcReconfigurationComplete; + rrcReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id; + rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete = CALLOC(1, sizeof(NR_RRCReconfigurationComplete_IEs_t)); + rrcReconfigurationComplete->criticalExtensions.present = + NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete; + rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->nonCriticalExtension = NULL; + rrcReconfigurationComplete->criticalExtensions.choice.rrcReconfigurationComplete->lateNonCriticalExtension = NULL; + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, + NULL, + (void *)&ul_dcch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + LOG_I(NR_RRC,"rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} + +uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){ + asn_enc_rval_t enc_rval; + + NR_UL_DCCH_Message_t ul_dcch_msg; + NR_RRCSetupComplete_t *RrcSetupComplete; + memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + + uint8_t buf[6]; + + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1)); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete; + ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_t)); + RrcSetupComplete = ul_dcch_msg.message.choice.c1->choice.rrcSetupComplete; + RrcSetupComplete->rrc_TransactionIdentifier = Transaction_id; + RrcSetupComplete->criticalExtensions.present = NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete = CALLOC(1, sizeof(NR_RRCSetupComplete_IEs_t)); + // RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension = CALLOC(1, + // sizeof(*RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->nonCriticalExtension)); + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->selectedPLMN_Identity = sel_plmn_id; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->registeredAMF = NULL; + + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value)); + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size = 6; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf = buf; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[0] = 0x12; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[1] = 0x34; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[2] = 0x56; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[3] = 0x78; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[4] = 0x9A; + RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.buf[5] = 0xBC; + + memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength); +if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); +} + +enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, + NULL, + (void *)&ul_dcch_msg, + buffer, + 100); +AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name,enc_rval.encoded); +LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + +return((enc_rval.encoded+7)/8); +} + +//------------------------------------------------------------------------------ +uint8_t +do_NR_DLInformationTransfer( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer +) +//------------------------------------------------------------------------------ +{ + ssize_t encoded; + NR_DL_DCCH_Message_t dl_dcch_msg; + memset(&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_DL_DCCH_MessageType__c1)); + dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer; + + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_t)); + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->rrc_TransactionIdentifier = transaction_id; + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer->criticalExtensions.present = + NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer; + + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> + criticalExtensions.choice.dlInformationTransfer = CALLOC(1, sizeof(NR_DLInformationTransfer_IEs_t)); + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> + criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> + criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer; + dl_dcch_msg.message.choice.c1->choice.dlInformationTransfer-> + criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message->size = pdu_length; + + encoded = uper_encode_to_new_buffer (&asn_DEF_NR_DL_DCCH_Message, NULL, (void *) &dl_dcch_msg, (void **)buffer); + AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n", + "DLInformationTransfer", encoded); + LOG_D(NR_RRC,"DLInformationTransfer Encoded %zd bytes\n", encoded); + return encoded; +} + +uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer) { + ssize_t encoded; + NR_UL_DCCH_Message_t ul_dcch_msg; + memset(&ul_dcch_msg, 0, sizeof(NR_UL_DCCH_Message_t)); + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = CALLOC(1,sizeof(struct NR_UL_DCCH_MessageType__c1)); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer; + ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer = CALLOC(1,sizeof(struct NR_ULInformationTransfer)); + ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.present = NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer; + ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer = CALLOC(1,sizeof(struct NR_ULInformationTransfer_IEs)); + struct NR_ULInformationTransfer_IEs *ulInformationTransfer = ul_dcch_msg.message.choice.c1->choice.ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer; + ulInformationTransfer->dedicatedNAS_Message = CALLOC(1,sizeof(NR_DedicatedNAS_Message_t)); + ulInformationTransfer->dedicatedNAS_Message->buf = pdu_buffer; + ulInformationTransfer->dedicatedNAS_Message->size = pdu_length; + ulInformationTransfer->lateNonCriticalExtension = NULL; + encoded = uper_encode_to_new_buffer (&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, (void **) buffer); + AssertFatal(encoded > 0,"ASN1 message encoding failed (%s, %ld)!\n", + "ULInformationTransfer",encoded); + LOG_D(NR_RRC,"ULInformationTransfer Encoded %zd bytes\n",encoded); + + return encoded; +} + +uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti) { + asn_enc_rval_t enc_rval; + NR_UL_CCCH_Message_t ul_ccch_msg; + NR_RRCReestablishmentRequest_t *rrcReestablishmentRequest; + uint8_t buf[2]; + + memset((void *)&ul_ccch_msg,0,sizeof(NR_UL_CCCH_Message_t)); + ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1; + ul_ccch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_CCCH_MessageType__c1)); + ul_ccch_msg.message.choice.c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest; + ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest = CALLOC(1, sizeof(NR_RRCReestablishmentRequest_t)); + + rrcReestablishmentRequest = ul_ccch_msg.message.choice.c1->choice.rrcReestablishmentRequest; + // test + rrcReestablishmentRequest->rrcReestablishmentRequest.reestablishmentCause = NR_ReestablishmentCause_reconfigurationFailure; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.c_RNTI = c_rnti; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.physCellId = 0; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf = buf; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[0] = 0x08; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[1] = 0x32; + rrcReestablishmentRequest->rrcReestablishmentRequest.ue_Identity.shortMAC_I.size = 2; + + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_ccch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_CCCH_Message, + NULL, + (void *)&ul_ccch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + LOG_D(NR_RRC,"[UE] RRCReestablishmentRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} + +//------------------------------------------------------------------------------ +uint8_t +do_RRCReestablishment( +const protocol_ctxt_t *const ctxt_pP, +rrc_gNB_ue_context_t *const ue_context_pP, +int CC_id, +uint8_t *const buffer, +//const uint8_t transmission_mode, +const uint8_t Transaction_id, +NR_SRB_ToAddModList_t **SRB_configList +) { + asn_enc_rval_t enc_rval; + //long *logicalchannelgroup = NULL; + struct NR_SRB_ToAddMod *SRB1_config = NULL; + struct NR_SRB_ToAddMod *SRB2_config = NULL; + //gNB_RRC_INST *nrrrc = RC.nrrrc[ctxt_pP->module_id]; + NR_DL_DCCH_Message_t dl_dcch_msg; + NR_RRCReestablishment_t *rrcReestablishment = NULL; + int i = 0; + ue_context_pP->ue_context.reestablishment_xid = Transaction_id; + NR_SRB_ToAddModList_t **SRB_configList2 = NULL; + SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; + + if (*SRB_configList2) { + free(*SRB_configList2); + } + + *SRB_configList2 = CALLOC(1, sizeof(NR_SRB_ToAddModList_t)); + memset((void *)&dl_dcch_msg, 0, sizeof(NR_DL_DCCH_Message_t)); + dl_dcch_msg.message.present = NR_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1 = calloc(1,sizeof(struct NR_DL_DCCH_MessageType__c1)); + dl_dcch_msg.message.choice.c1->present = NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment; + dl_dcch_msg.message.choice.c1->choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_t)); + rrcReestablishment = dl_dcch_msg.message.choice.c1->choice.rrcReestablishment; + + // get old configuration of SRB2 + if (*SRB_configList != NULL) { + for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) { + LOG_D(NR_RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n", + i, (*SRB_configList)->list.array[i]->srb_Identity); + + if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ) { + SRB2_config = (*SRB_configList)->list.array[i]; + } else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ) { + SRB1_config = (*SRB_configList)->list.array[i]; + } + } + } + + if (SRB1_config == NULL) { + // default SRB1 configuration + LOG_W(NR_RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n"); + /// SRB1 + SRB1_config = CALLOC(1, sizeof(*SRB1_config)); + SRB1_config->srb_Identity = 1; + } + + if (SRB2_config == NULL) { + LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n"); + } else { + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + } + + if (*SRB_configList) { + free(*SRB_configList); + } + + *SRB_configList = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t)); + ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config); + + rrcReestablishment->rrc_TransactionIdentifier = Transaction_id; + rrcReestablishment->criticalExtensions.present = NR_RRCReestablishment__criticalExtensions_PR_rrcReestablishment; + rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1,sizeof(NR_RRCReestablishment_IEs_t)); + + uint8_t KgNB_star[32] = { 0 }; + /** TODO + uint16_t pci = nrrrc->carrier[CC_id].physCellId; + uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band, + nrrrc->carrier[CC_id].dl_CarrierFreq); + bool is_rel8_only = true; + + if (earfcn_dl > 65535) { + is_rel8_only = false; + } + LOG_D(NR_RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n", + pci, + RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band, + nrrrc->carrier[CC_id].dl_CarrierFreq, + earfcn_dl, + is_rel8_only == true ? "true": "false"); + */ + + if (ue_context_pP->ue_context.nh_ncc >= 0) { + //TODO derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KgNB_star); + rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = ue_context_pP->ue_context.nh_ncc; + } else { // first HO + //TODO derive_keNB_star (ue_context_pP->ue_context.kgnb, pci, earfcn_dl, is_rel8_only, KgNB_star); + // LG: really 1 + rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = 0; + } + // copy KgNB_star to ue_context_pP->ue_context.kgnb + memcpy (ue_context_pP->ue_context.kgnb, KgNB_star, 32); + ue_context_pP->ue_context.kgnb_ncc = 0; + rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL; + rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)&dl_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_DL_DCCH_Message, + NULL, + (void *)&dl_dcch_msg, + buffer, + 100); + + if(enc_rval.encoded == -1) { + LOG_E(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + LOG_D(NR_RRC,"RRCReestablishment Encoded %u bits (%u bytes)\n", + (uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); + +} + +uint8_t +do_RRCReestablishmentComplete(uint8_t *buffer, int64_t rrc_TransactionIdentifier) { + asn_enc_rval_t enc_rval; + NR_UL_DCCH_Message_t ul_dcch_msg; + NR_RRCReestablishmentComplete_t *rrcReestablishmentComplete; + + memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete; + ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_t)); + + rrcReestablishmentComplete = ul_dcch_msg.message.choice.c1->choice.rrcReestablishmentComplete; + rrcReestablishmentComplete->rrc_TransactionIdentifier = rrc_TransactionIdentifier; + rrcReestablishmentComplete->criticalExtensions.present = NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete; + rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete = CALLOC(1, sizeof(NR_RRCReestablishmentComplete_IEs_t)); + rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->lateNonCriticalExtension = NULL; + rrcReestablishmentComplete->criticalExtensions.choice.rrcReestablishmentComplete->nonCriticalExtension = NULL; + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_CCCH_Message, (void *)&ul_dcch_msg); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, + NULL, + (void *)&ul_dcch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} + diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 3f647cb887..bfc4942138 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -82,3 +82,86 @@ void do_PHYSICALCELLGROUP(uint8_t Mod_id, void do_SpCellConfig(gNB_RRC_INST *rrc, struct NR_SpCellConfig *spconfig); + +uint8_t do_RRCReject(uint8_t Mod_id, + uint8_t *const buffer); + +uint8_t do_RRCSetup(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + int CC_id, + uint8_t *const buffer, + const uint8_t transaction_id, + NR_SRB_ToAddModList_t **SRB_configList); +uint8_t do_NR_SecurityModeCommand( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + NR_IntegrityProtAlgorithm_t *integrityProtAlgorithm); + +uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, + const uint8_t Transaction_id); + +uint8_t do_NR_RRCRelease(uint8_t *buffer, + uint8_t Transaction_id); +uint16_t do_RRCReconfiguration( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + NR_SRB_ToAddModList_t *SRB_configList, + NR_DRB_ToAddModList_t *DRB_configList, + NR_DRB_ToReleaseList_t *DRB_releaseList, + NR_SecurityConfig_t *security_config, + NR_SDAP_Config_t *sdap_config, + NR_MeasConfig_t *meas_config, + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList + *dedicatedNAS_MessageList, + NR_MAC_CellGroupConfig_t *mac_CellGroupConfig); + +uint8_t do_RRCSetupComplete(uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id, + uint8_t sel_plmn_id, + const int dedicatedInfoNASLength, + const char *dedicatedInfoNAS); + +uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); + +uint8_t do_NR_RRCReconfigurationComplete( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + const uint8_t Transaction_id + ); + +uint8_t +do_NR_DLInformationTransfer( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer +); + +uint8_t do_NR_ULInformationTransfer(uint8_t **buffer, + uint32_t pdu_length, + uint8_t *pdu_buffer); + +uint8_t do_RRCReestablishmentRequest(uint8_t Mod_id, uint8_t *buffer, uint16_t c_rnti); + +uint8_t +do_RRCReestablishment( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + int CC_id, + uint8_t *const buffer, + //const uint8_t transmission_mode, + const uint8_t Transaction_id, + NR_SRB_ToAddModList_t **SRB_configList +); + +uint8_t +do_RRCReestablishmentComplete( + uint8_t *buffer, + int64_t rrc_TransactionIdentifier); + diff --git a/openair2/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.1.0.asn1 b/openair2/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.1.0.asn1 new file mode 100644 index 0000000000..353e3e398f --- /dev/null +++ b/openair2/RRC/NR/MESSAGES/asn1c/ASN1_files/nr-rrc-16.1.0.asn1 @@ -0,0 +1,12881 @@ +NR-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- TAG-BCCH-BCH-MESSAGE-START + +BCCH-BCH-Message ::= SEQUENCE { + message BCCH-BCH-MessageType +} + +BCCH-BCH-MessageType ::= CHOICE { + mib MIB, + messageClassExtension SEQUENCE {} +} + +-- TAG-BCCH-BCH-MESSAGE-STOP +-- TAG-BCCH-DL-SCH-MESSAGE-START + +BCCH-DL-SCH-Message ::= SEQUENCE { + message BCCH-DL-SCH-MessageType +} + +BCCH-DL-SCH-MessageType ::= CHOICE { + c1 CHOICE { + systemInformation SystemInformation, + systemInformationBlockType1 SIB1 + }, + messageClassExtension SEQUENCE {} +} + +-- TAG-BCCH-DL-SCH-MESSAGE-STOP +-- TAG-DL-CCCH-MESSAGE-START + +DL-CCCH-Message ::= SEQUENCE { + message DL-CCCH-MessageType +} + +DL-CCCH-MessageType ::= CHOICE { + c1 CHOICE { + rrcReject RRCReject, + rrcSetup RRCSetup, + spare2 NULL, + spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + +-- TAG-DL-CCCH-MESSAGE-STOP +-- TAG-DL-DCCH-MESSAGE-START + +DL-DCCH-Message ::= SEQUENCE { + message DL-DCCH-MessageType +} + +DL-DCCH-MessageType ::= CHOICE { + c1 CHOICE { + rrcReconfiguration RRCReconfiguration, + rrcResume RRCResume, + rrcRelease RRCRelease, + rrcReestablishment RRCReestablishment, + securityModeCommand SecurityModeCommand, + dlInformationTransfer DLInformationTransfer, + ueCapabilityEnquiry UECapabilityEnquiry, + counterCheck CounterCheck, + mobilityFromNRCommand MobilityFromNRCommand, + dlDedicatedMessageSegment-r16 DLDedicatedMessageSegment-r16, + ueInformationRequest-r16 UEInformationRequest-r16, + dlInformationTransferMRDC-r16 DLInformationTransferMRDC-r16, + loggedMeasurementConfiguration-r16 LoggedMeasurementConfiguration-r16, + spare3 NULL, spare2 NULL, spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + +-- TAG-DL-DCCH-MESSAGE-STOP +-- TAG-PCCH-PCH-MESSAGE-START + +PCCH-Message ::= SEQUENCE { + message PCCH-MessageType +} + +PCCH-MessageType ::= CHOICE { + c1 CHOICE { + paging Paging, + spare1 NULL + }, + messageClassExtension SEQUENCE {} +} + +-- TAG-PCCH-PCH-MESSAGE-STOP +-- TAG-UL-CCCH-MESSAGE-START + + +UL-CCCH-Message ::= SEQUENCE { + message UL-CCCH-MessageType +} + +UL-CCCH-MessageType ::= CHOICE { + c1 CHOICE { + rrcSetupRequest RRCSetupRequest, + rrcResumeRequest RRCResumeRequest, + rrcReestablishmentRequest RRCReestablishmentRequest, + rrcSystemInfoRequest RRCSystemInfoRequest + }, + messageClassExtension SEQUENCE {} +} + +-- TAG-UL-CCCH-MESSAGE-STOP +-- TAG-UL-CCCH1-MESSAGE-START + + +UL-CCCH1-Message ::= SEQUENCE { + message UL-CCCH1-MessageType +} + +UL-CCCH1-MessageType ::= CHOICE { + c1 CHOICE { + rrcResumeRequest1 RRCResumeRequest1, + spare3 NULL, + spare2 NULL, + spare1 NULL + + }, + messageClassExtension SEQUENCE {} +} + +-- TAG-UL-CCCH1-MESSAGE-STOP +-- TAG-UL-DCCH-MESSAGE-START + +UL-DCCH-Message ::= SEQUENCE { + message UL-DCCH-MessageType +} + +UL-DCCH-MessageType ::= CHOICE { + c1 CHOICE { + measurementReport MeasurementReport, + rrcReconfigurationComplete RRCReconfigurationComplete, + rrcSetupComplete RRCSetupComplete, + rrcReestablishmentComplete RRCReestablishmentComplete, + rrcResumeComplete RRCResumeComplete, + securityModeComplete SecurityModeComplete, + securityModeFailure SecurityModeFailure, + ulInformationTransfer ULInformationTransfer, + locationMeasurementIndication LocationMeasurementIndication, + ueCapabilityInformation UECapabilityInformation, + counterCheckResponse CounterCheckResponse, + ueAssistanceInformation UEAssistanceInformation, + failureInformation FailureInformation, + ulInformationTransferMRDC ULInformationTransferMRDC, + scgFailureInformation SCGFailureInformation, + scgFailureInformationEUTRA SCGFailureInformationEUTRA + }, + messageClassExtension CHOICE { + c2 CHOICE { + ulDedicatedMessageSegment-r16 ULDedicatedMessageSegment-r16, + dedicatedSIBRequest-r16 DedicatedSIBRequest-r16, + mcgFailureInformation-r16 MCGFailureInformation-r16, + ueInformationResponse-r16 UEInformationResponse-r16, + sidelinkUEInformationNR-r16 SidelinkUEInformationNR-r16, + ulInformationTransferIRAT-r16 ULInformationTransferIRAT-r16, + iabOtherInformation-r16 IABOtherInformation-r16, + spare9 NULL, spare8 NULL, spare7 NULL, spare6 NULL, + spare5 NULL, spare4 NULL, spare3 NULL, spare2 NULL, spare1 NULL + }, + messageClassExtensionFuture-r16 SEQUENCE {} + } +} + +-- TAG-UL-DCCH-MESSAGE-STOP +-- TAG-COUNTERCHECK-START + + +CounterCheck ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + counterCheck CounterCheck-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +CounterCheck-IEs ::= SEQUENCE { + drb-CountMSB-InfoList DRB-CountMSB-InfoList, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +DRB-CountMSB-InfoList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info + +DRB-CountMSB-Info ::= SEQUENCE { + drb-Identity DRB-Identity, + countMSB-Uplink INTEGER(0..33554431), + countMSB-Downlink INTEGER(0..33554431) +} + +-- TAG-COUNTERCHECK-STOP +-- TAG-COUNTERCHECKRESPONSE-START + +CounterCheckResponse ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + counterCheckResponse CounterCheckResponse-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +CounterCheckResponse-IEs ::= SEQUENCE { + drb-CountInfoList DRB-CountInfoList, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL + +} + +DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo + +DRB-CountInfo ::= SEQUENCE { + drb-Identity DRB-Identity, + count-Uplink INTEGER(0..4294967295), + count-Downlink INTEGER(0..4294967295) +} + +-- TAG-COUNTERCHECKRESPONSE-STOP +-- TAG-DEDICATEDSIBREQUEST-START + +DedicatedSIBRequest-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + dedicatedSIBRequest-r16 DedicatedSIBRequest-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +DedicatedSIBRequest-r16-IEs ::= SEQUENCE { + onDemandSIB-RequestList-r16 SEQUENCE { + + requestedSIB-List-r16 SEQUENCE (SIZE (1..maxOnDemandSIB-r16)) OF SIB-ReqInfo-r16 OPTIONAL, + requestedPosSIB-List-r16 SEQUENCE (SIZE (1..maxOnDemandPosSIB-r16)) OF PosSIB-ReqInfo-r16 OPTIONAL + } OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +SIB-ReqInfo-r16 ::= ENUMERATED { sib12, sib13, sib14, spare5, spare4, spare3, spare2, spare1 } + +PosSIB-ReqInfo-r16 ::= SEQUENCE { + gnss-id-r16 GNSS-ID-r16 OPTIONAL, + sbas-id-r16 SBAS-ID-r16 OPTIONAL, + posSibType-r16 ENUMERATED { posSibType1-1, posSibType1-2, posSibType1-3, posSibType1-4, posSibType1-5, posSibType1-6, + posSibType1-7, posSibType1-8, posSibType2-1, posSibType2-2, posSibType2-3, posSibType2-4, + posSibType2-5, posSibType2-6, posSibType2-7, posSibType2-8, posSibType2-9, posSibType2-10, + posSibType2-11, posSibType2-12, posSibType2-13, posSibType2-14, posSibType2-15, + posSibType2-16, posSibType2-17, posSibType2-18, posSibType2-19, posSibType2-20, + posSibType2-21, posSibType2-22, posSibType2-23, posSibType3-1, posSibType4-1, + posSibType5-1, posSibType6-1, posSibType6-2, posSibType6-3,... } +} + +-- TAG-DEDICATEDSIBREQUEST-STOP +-- TAG-DLDEDICATEDMESSAGESEGMENT-START + + +DLDedicatedMessageSegment-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + dlDedicatedMessageSegment-r16 DLDedicatedMessageSegment-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +DLDedicatedMessageSegment-r16-IEs ::= SEQUENCE { + segmentNumber-r16 INTEGER(0..4), + rrc-MessageSegmentContainer-r16 OCTET STRING, + rrc-MessageSegmentType-r16 ENUMERATED {notLastSegment, lastSegment}, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-DLDEDICATEDMESSAGESEGMENT-STOP +-- TAG-DLINFORMATIONTRANSFER-START + +DLInformationTransfer ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + dlInformationTransfer DLInformationTransfer-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +DLInformationTransfer-IEs ::= SEQUENCE { + dedicatedNAS-Message DedicatedNAS-Message OPTIONAL, -- Need N + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension DLInformationTransfer-v1610-IEs OPTIONAL +} + +DLInformationTransfer-v1610-IEs ::= SEQUENCE { + referenceTimeInfo-r16 ReferenceTimeInfo-r16 OPTIONAL, -- Need R + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-DLINFORMATIONTRANSFER-STOP +-- TAG-DLINFORMATIONTRANSFERMRDC-START + +DLInformationTransferMRDC-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + dlInformationTransferMRDC-r16 DLInformationTransferMRDC-r16-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +DLInformationTransferMRDC-r16-IEs::= SEQUENCE { + dl-DCCH-MessageNR-r16 OCTET STRING OPTIONAL, -- Need N + dl-DCCH-MessageEUTRA-r16 OCTET STRING OPTIONAL, -- Need N + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-DLINFORMATIONTRANSFERMRDC-STOP +-- TAG-FAILUREINFORMATION-START + +FailureInformation ::= SEQUENCE { + criticalExtensions CHOICE { + failureInformation FailureInformation-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +FailureInformation-IEs ::= SEQUENCE { + failureInfoRLC-Bearer FailureInfoRLC-Bearer OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension FailureInformation-v1610-IEs OPTIONAL +} + +FailureInfoRLC-Bearer ::= SEQUENCE { + cellGroupId CellGroupId, + logicalChannelIdentity LogicalChannelIdentity, + failureType ENUMERATED {rlc-failure, spare3, spare2, spare1} +} + +FailureInformation-v1610-IEs ::= SEQUENCE { + failureInfoDAPS-r16 FailureInfoDAPS-r16 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +FailureInfoDAPS-r16 ::= SEQUENCE { + failureType-r16 ENUMERATED {daps-failure, spare3, spare2, spare1} +} + +-- TAG-FAILUREINFORMATION-STOP +-- TAG-IABOTHERINFORMATION-START + +IABOtherInformation-r16 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + iabOtherInformation-r16 IABOtherInformation-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +IABOtherInformation-r16-IEs ::= SEQUENCE { + ip-InfoType CHOICE { + iab-IP-Request-r16 SEQUENCE { + iab-IPv4-AddressNumReq-r16 IAB-IPAddressNumReq-r16 OPTIONAL, + iab-IPv6-AddressReq-r16 CHOICE { + iab-IPv6-AddressNumReq-r16 IAB-IPAddressNumReq-r16, + iab-IPv6-AddressPrefixReq-r16 IAB-IPAddressPrefixReq-r16, + ... + } OPTIONAL + }, + iab-IP-Report-r16 SEQUENCE { + iab-IPv4-AddressReport-r16 IAB-IP-AddressAndTraffic-r16 OPTIONAL, + iab-IPv6-Report-r16 CHOICE { + iab-IPv6-AddressReport-r16 IAB-IP-AddressAndTraffic-r16, + iab-IPv6-PrefixReport-r16 IAB-IP-PrefixAndTraffic-r16, + ... + } OPTIONAL + }, + ... + }, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +IAB-IPAddressNumReq-r16 ::= SEQUENCE { + all-Traffic-NumReq-r16 INTEGER (1..8) OPTIONAL, + f1-C-Traffic-NumReq-r16 INTEGER (1..8) OPTIONAL, + f1-U-Traffic-NumReq-r16 INTEGER (1..8) OPTIONAL, + non-F1-Traffic-NumReq-r16 INTEGER (1..8) OPTIONAL, + ... +} + +IAB-IPAddressPrefixReq-r16 ::= SEQUENCE { + all-Traffic-PrefixReq-r16 ENUMERATED {true} OPTIONAL, + f1-C-Traffic-PrefixReq-r16 ENUMERATED {true} OPTIONAL, + f1-U-Traffic-PrefixReq-r16 ENUMERATED {true} OPTIONAL, + non-F1-Traffic-PrefixReq-r16 ENUMERATED {true} OPTIONAL, + ... +} + +IAB-IP-AddressAndTraffic-r16 ::= SEQUENCE { + all-Traffic-IAB-IP-Address-r16 SEQUENCE (SIZE(1..8)) OF IAB-IP-Address-r16 OPTIONAL, + f1-C-Traffic-IP-Address-r16 SEQUENCE (SIZE(1..8)) OF IAB-IP-Address-r16 OPTIONAL, + f1-U-Traffic-IP-Address-r16 SEQUENCE (SIZE(1..8)) OF IAB-IP-Address-r16 OPTIONAL, + non-F1-Traffic-IP-Address-r16 SEQUENCE (SIZE(1..8)) OF IAB-IP-Address-r16 OPTIONAL +} + +IAB-IP-PrefixAndTraffic-r16 ::= SEQUENCE { + all-Traffic-IAB-IP-Address-r16 IAB-IP-Address-r16 OPTIONAL, + f1-C-Traffic-IP-Address-r16 IAB-IP-Address-r16 OPTIONAL, + f1-U-Traffic-IP-Address-r16 IAB-IP-Address-r16 OPTIONAL, + non-F1-Traffic-IP-Address-r16 IAB-IP-Address-r16 OPTIONAL +} + +-- TAG-IABOTHERINFORMATION-STOP +-- TAG-LOCATIONMEASUREMENTINDICATION-START + +LocationMeasurementIndication ::= SEQUENCE { + criticalExtensions CHOICE { + locationMeasurementIndication LocationMeasurementIndication-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +LocationMeasurementIndication-IEs ::= SEQUENCE { + measurementIndication SetupRelease {LocationMeasurementInfo}, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-LOCATIONMEASUREMENTINDICATION-STOP +-- TAG-LOGGEDMEASUREMENTCONFIGURATION-START + +LoggedMeasurementConfiguration-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + loggedMeasurementConfiguration-r16 LoggedMeasurementConfiguration-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +LoggedMeasurementConfiguration-r16-IEs ::= SEQUENCE { + traceReference-r16 TraceReference-r16, + traceRecordingSessionRef-r16 OCTET STRING (SIZE (2)), + tce-Id-r16 OCTET STRING (SIZE (1)), + absoluteTimeInfo-r16 AbsoluteTimeInfo-r16, + areaConfiguration-r16 AreaConfiguration-r16 OPTIONAL, --Need R + plmn-IdentityList-r16 PLMN-IdentityList2-r16 OPTIONAL, --Need R + bt-NameList-r16 SetupRelease {BT-NameList-r16} OPTIONAL, --Need M + wlan-NameList-r16 SetupRelease {WLAN-NameList-r16} OPTIONAL, --Need M + sensor-NameList-r16 SetupRelease {Sensor-NameList-r16} OPTIONAL, --Need M + loggingDuration-r16 LoggingDuration-r16, + reportType CHOICE { + periodical LoggedPeriodicalReportConfig-r16, + eventTriggered LoggedEventTriggerConfig-r16, + ... + }, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +LoggedPeriodicalReportConfig-r16 ::= SEQUENCE { + loggingInterval-r16 LoggingInterval-r16, + ... + } + +LoggedEventTriggerConfig-r16 ::= SEQUENCE { + eventType-r16 EventType-r16, + loggingInterval-r16 LoggingInterval-r16, + ... +} + +EventType-r16 ::= CHOICE { + outOfCoverage NULL, + eventL1 SEQUENCE { + l1-Threshold MeasTriggerQuantity, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + ... +} + +-- TAG-LOGGEDMEASUREMENTCONFIGURATION-STOP +-- TAG-MCGFAILUREINFORMATION-START + +MCGFailureInformation-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + mcgFailureInformation-r16 MCGFailureInformation-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +MCGFailureInformation-r16-IEs ::= SEQUENCE { + failureReportMCG-r16 FailureReportMCG-r16 OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +FailureReportMCG-r16 ::= SEQUENCE { + failureType-r16 ENUMERATED {t310-Expiry, randomAccessProblem, rlc-MaxNumRetx, + t312-Expiry-r16, lbt-Failure-r16, beamFailureRecoveryFailure-r16, + bh-RLF-r16, spare1} OPTIONAL, + measResultFreqList-r16 MeasResultList2NR OPTIONAL, + measResultFreqListEUTRA-r16 MeasResultList2EUTRA OPTIONAL, + measResultSCG-r16 OCTET STRING (CONTAINING MeasResultSCG-Failure) OPTIONAL, + measResultSCG-EUTRA-r16 OCTET STRING OPTIONAL, + measResultFreqListUTRA-FDD-r16 MeasResultList2UTRA OPTIONAL, + ... +} + +MeasResultList2UTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2UTRA-FDD-r16 + +MeasResult2UTRA-FDD-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueUTRA-FDD-r16, + measResultNeighCellList-r16 MeasResultListUTRA-FDD-r16 +} + +MeasResultList2EUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2EUTRA-r16 + +-- TAG-MCGFAILUREINFORMATION-STOP +-- TAG-MEASUREMENTREPORT-START + +MeasurementReport ::= SEQUENCE { + criticalExtensions CHOICE { + measurementReport MeasurementReport-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +MeasurementReport-IEs ::= SEQUENCE { + measResults MeasResults, + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-MEASUREMENTREPORT-STOP +-- TAG-MIB-START + +MIB ::= SEQUENCE { + systemFrameNumber BIT STRING (SIZE (6)), + subCarrierSpacingCommon ENUMERATED {scs15or60, scs30or120}, + ssb-SubcarrierOffset INTEGER (0..15), + dmrs-TypeA-Position ENUMERATED {pos2, pos3}, + pdcch-ConfigSIB1 PDCCH-ConfigSIB1, + cellBarred ENUMERATED {barred, notBarred}, + intraFreqReselection ENUMERATED {allowed, notAllowed}, + spare BIT STRING (SIZE (1)) +} + +-- TAG-MIB-STOP +-- TAG-MOBILITYFROMNRCOMMAND-START + +MobilityFromNRCommand ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + mobilityFromNRCommand MobilityFromNRCommand-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +MobilityFromNRCommand-IEs ::= SEQUENCE { + targetRAT-Type ENUMERATED { eutra, utra-fdd-v1610, spare2, spare1, ...}, + targetRAT-MessageContainer OCTET STRING, + nas-SecurityParamFromNR OCTET STRING OPTIONAL, -- Cond HO-ToEPCUTRAN + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension MobilityFromNRCommand-v1610-IEs OPTIONAL +} + +MobilityFromNRCommand-v1610-IEs ::= SEQUENCE { + voiceFallbackIndication-r16 ENUMERATED {true} OPTIONAL, -- Need N + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-MOBILITYFROMNRCOMMAND-STOP +-- TAG-PAGING-START + +Paging ::= SEQUENCE { + pagingRecordList PagingRecordList OPTIONAL, -- Need N + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +PagingRecordList ::= SEQUENCE (SIZE(1..maxNrofPageRec)) OF PagingRecord + +PagingRecord ::= SEQUENCE { + ue-Identity PagingUE-Identity, + accessType ENUMERATED {non3GPP} OPTIONAL, -- Need N + ... +} + +PagingUE-Identity ::= CHOICE { + ng-5G-S-TMSI NG-5G-S-TMSI, + fullI-RNTI I-RNTI-Value, + ... +} + +-- TAG-PAGING-STOP +-- TAG-RRCREESTABLISHMENT-START + +RRCReestablishment ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcReestablishment RRCReestablishment-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCReestablishment-IEs ::= SEQUENCE { + nextHopChainingCount NextHopChainingCount, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-RRCREESTABLISHMENT-STOP +-- TAG-RRCREESTABLISHMENTCOMPLETE-START + +RRCReestablishmentComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcReestablishmentComplete RRCReestablishmentComplete-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCReestablishmentComplete-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCReestablishmentComplete-v1610-IEs OPTIONAL +} + +RRCReestablishmentComplete-v1610-IEs ::= SEQUENCE { + ueMeasurementsAvailable-r16 UEMeasurementsAvailable-r16 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-RRCREESTABLISHMENTCOMPLETE-STOP +-- TAG-RRCREESTABLISHMENTREQUEST-START + + +RRCReestablishmentRequest ::= SEQUENCE { + rrcReestablishmentRequest RRCReestablishmentRequest-IEs +} + +RRCReestablishmentRequest-IEs ::= SEQUENCE { + ue-Identity ReestabUE-Identity, + reestablishmentCause ReestablishmentCause, + spare BIT STRING (SIZE (1)) +} + +ReestabUE-Identity ::= SEQUENCE { + c-RNTI RNTI-Value, + physCellId PhysCellId, + shortMAC-I ShortMAC-I +} + +ReestablishmentCause ::= ENUMERATED {reconfigurationFailure, handoverFailure, otherFailure, spare1} + +-- TAG-RRCREESTABLISHMENTREQUEST-STOP +-- TAG-RRCRECONFIGURATION-START + +RRCReconfiguration ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcReconfiguration RRCReconfiguration-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCReconfiguration-IEs ::= SEQUENCE { + radioBearerConfig RadioBearerConfig OPTIONAL, -- Need M + secondaryCellGroup OCTET STRING (CONTAINING CellGroupConfig) OPTIONAL, -- Cond SCG + measConfig MeasConfig OPTIONAL, -- Need M + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCReconfiguration-v1530-IEs OPTIONAL +} + +RRCReconfiguration-v1530-IEs ::= SEQUENCE { + masterCellGroup OCTET STRING (CONTAINING CellGroupConfig) OPTIONAL, -- Need M + fullConfig ENUMERATED {true} OPTIONAL, -- Cond FullConfig + dedicatedNAS-MessageList SEQUENCE (SIZE(1..maxDRB)) OF DedicatedNAS-Message OPTIONAL, -- Cond nonHO + masterKeyUpdate MasterKeyUpdate OPTIONAL, -- Cond MasterKeyChange + dedicatedSIB1-Delivery OCTET STRING (CONTAINING SIB1) OPTIONAL, -- Need N + dedicatedSystemInformationDelivery OCTET STRING (CONTAINING SystemInformation) OPTIONAL, -- Need N + otherConfig OtherConfig OPTIONAL, -- Need M + nonCriticalExtension RRCReconfiguration-v1540-IEs OPTIONAL +} + +RRCReconfiguration-v1540-IEs ::= SEQUENCE { + otherConfig-v1540 OtherConfig-v1540 OPTIONAL, -- Need M + nonCriticalExtension RRCReconfiguration-v1560-IEs OPTIONAL +} + +RRCReconfiguration-v1560-IEs ::= SEQUENCE { + mrdc-SecondaryCellGroupConfig SetupRelease { MRDC-SecondaryCellGroupConfig } OPTIONAL, -- Need M + radioBearerConfig2 OCTET STRING (CONTAINING RadioBearerConfig) OPTIONAL, -- Need M + sk-Counter SK-Counter OPTIONAL, -- Need N + nonCriticalExtension RRCReconfiguration-v1610-IEs OPTIONAL +} +RRCReconfiguration-v1610-IEs ::= SEQUENCE { + otherConfig-v1610 OtherConfig-v1610 OPTIONAL, -- Need M + bap-Config-r16 SetupRelease { BAP-Config-r16 } OPTIONAL, -- Need M + iab-IP-AddressConfigurationList-r16 IAB-IP-AddressConfigurationList-r16 OPTIONAL, -- Need M + conditionalReconfiguration-r16 ConditionalReconfiguration-r16 OPTIONAL, -- Need M + daps-SourceRelease-r16 ENUMERATED{true} OPTIONAL, -- Need N + t316-r16 SetupRelease {T316-r16} OPTIONAL, -- Need M + needForGapsConfigNR-r16 SetupRelease {NeedForGapsConfigNR-r16} OPTIONAL, -- Need M + onDemandSIB-Request-r16 SetupRelease { OnDemandSIB-Request-r16 } OPTIONAL, -- Need M + dedicatedPosSysInfoDelivery-r16 OCTET STRING (CONTAINING PosSystemInformation-r16-IEs) OPTIONAL, -- Need N + sl-ConfigDedicatedNR-r16 SetupRelease {SL-ConfigDedicatedNR-r16} OPTIONAL, -- Need M + sl-ConfigDedicatedEUTRA-Info-r16 SetupRelease {SL-ConfigDedicatedEUTRA-Info-r16} OPTIONAL, -- Need M + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +MRDC-SecondaryCellGroupConfig ::= SEQUENCE { + mrdc-ReleaseAndAdd ENUMERATED {true} OPTIONAL, -- Need N + mrdc-SecondaryCellGroup CHOICE { + nr-SCG OCTET STRING (CONTAINING RRCReconfiguration), + eutra-SCG OCTET STRING + } +} + +BAP-Config-r16 ::= SEQUENCE { + bap-Address-r16 BIT STRING (SIZE (10)) OPTIONAL, -- Need M + defaultUL-BAProutingID-r16 BAP-Routing-ID-r16 OPTIONAL, -- Need M + defaultUL-BH-RLC-Channel-r16 BH-RLC-ChannelID-r16 OPTIONAL, -- Need M + flowControlFeedbackType-r16 ENUMERATED {perBH-RLC-Channel, perRoutingID, both} OPTIONAL, -- Need R + ... +} + +MasterKeyUpdate ::= SEQUENCE { + keySetChangeIndicator BOOLEAN, + nextHopChainingCount NextHopChainingCount, + nas-Container OCTET STRING OPTIONAL, -- Cond securityNASC + ... +} + +OnDemandSIB-Request-r16 ::= SEQUENCE { + onDemandSIB-RequestProhibitTimer-r16 ENUMERATED {s0, s0dot5, s1, s2, s5, s10, s20, s30} +} + +T316-r16 ::= ENUMERATED {ms50, ms100, ms200, ms300, ms400, ms500, ms600, ms1000, ms1500, ms2000} + +IAB-IP-AddressConfigurationList-r16 ::= SEQUENCE { + iab-IP-AddressToAddModList-r16 SEQUENCE (SIZE(1..maxIAB-IP-Address-r16)) OF IAB-IP-AddressConfiguration-r16 OPTIONAL, -- Need N + iab-IP-AddressToReleaseList-r16 SEQUENCE (SIZE(1..maxIAB-IP-Address-r16)) OF IAB-IP-AddressIndex-r16 OPTIONAL, -- Need N + ... +} + +IAB-IP-AddressConfiguration-r16 ::= SEQUENCE { + iab-IP-AddressIndex-r16 IAB-IP-AddressIndex-r16, + iab-IP-Address-r16 IAB-IP-Address-r16 OPTIONAL, -- Need M + iab-IP-Usage-r16 IAB-IP-Usage-r16 OPTIONAL, -- Need M + iab-donor-DU-BAP-Address-r16 BIT STRING (SIZE(10)) OPTIONAL, -- Need M +... +} + +SL-ConfigDedicatedEUTRA-Info-r16 ::= SEQUENCE { + sl-ConfigDedicatedEUTRA-r16 OCTET STRING OPTIONAL, -- Need M + sl-TimeOffsetEUTRA-List-r16 SEQUENCE (SIZE (8)) OF SL-TimeOffsetEUTRA-r16 OPTIONAL -- Need M +} + +SL-TimeOffsetEUTRA-r16 ::= ENUMERATED {ms0, ms0dot25, ms0dot5, ms0dot625, ms0dot75, ms1, ms1dot25, ms1dot5, ms1dot75, + ms2, ms2dot5, ms3, ms4, ms5, ms6, ms8, ms10, ms20} + +-- TAG-RRCRECONFIGURATION-STOP +-- TAG-RRCRECONFIGURATIONCOMPLETE-START + +RRCReconfigurationComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcReconfigurationComplete RRCReconfigurationComplete-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCReconfigurationComplete-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCReconfigurationComplete-v1530-IEs OPTIONAL +} + +RRCReconfigurationComplete-v1530-IEs ::= SEQUENCE { + uplinkTxDirectCurrentList UplinkTxDirectCurrentList OPTIONAL, + nonCriticalExtension RRCReconfigurationComplete-v1560-IEs OPTIONAL +} + +RRCReconfigurationComplete-v1560-IEs ::= SEQUENCE { + scg-Response CHOICE { + nr-SCG-Response OCTET STRING (CONTAINING RRCReconfigurationComplete), + eutra-SCG-Response OCTET STRING + } OPTIONAL, + nonCriticalExtension RRCReconfigurationComplete-v1610-IEs OPTIONAL +} + +RRCReconfigurationComplete-v1610-IEs ::= SEQUENCE { + ueMeasurementsAvailable-r16 UEMeasurementsAvailable-r16 OPTIONAL, + needForGapsInfoNR-r16 NeedForGapsInfoNR-r16 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-RRCRECONFIGURATIONCOMPLETE-STOP +-- TAG-RRCREJECT-START + +RRCReject ::= SEQUENCE { + criticalExtensions CHOICE { + rrcReject RRCReject-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCReject-IEs ::= SEQUENCE { + waitTime RejectWaitTime OPTIONAL, -- Need N + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-RRCREJECT-STOP +-- TAG-RRCRELEASE-START + +RRCRelease ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcRelease RRCRelease-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCRelease-IEs ::= SEQUENCE { + redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need N + cellReselectionPriorities CellReselectionPriorities OPTIONAL, -- Need R + suspendConfig SuspendConfig OPTIONAL, -- Need R + deprioritisationReq SEQUENCE { + deprioritisationType ENUMERATED {frequency, nr}, + deprioritisationTimer ENUMERATED {min5, min10, min15, min30} + } OPTIONAL, -- Need N + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCRelease-v1540-IEs OPTIONAL +} + +RRCRelease-v1540-IEs ::= SEQUENCE { + waitTime RejectWaitTime OPTIONAL, -- Need N + nonCriticalExtension RRCRelease-v1610-IEs OPTIONAL +} + +RRCRelease-v1610-IEs ::= SEQUENCE { + voiceFallbackIndication-r16 ENUMERATED {true} OPTIONAL, -- Need N + measIdleConfig-r16 SetupRelease {MeasIdleConfigDedicated-r16} OPTIONAL, -- Need M + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +RedirectedCarrierInfo ::= CHOICE { + nr CarrierInfoNR, + eutra RedirectedCarrierInfo-EUTRA, + ... +} + +RedirectedCarrierInfo-EUTRA ::= SEQUENCE { + eutraFrequency ARFCN-ValueEUTRA, + cnType ENUMERATED {epc,fiveGC} OPTIONAL -- Need N +} + +CarrierInfoNR ::= SEQUENCE { + carrierFreq ARFCN-ValueNR, + ssbSubcarrierSpacing SubcarrierSpacing, + smtc SSB-MTC OPTIONAL, -- Need S + ... +} + +SuspendConfig ::= SEQUENCE { + fullI-RNTI I-RNTI-Value, + shortI-RNTI ShortI-RNTI-Value, + ran-PagingCycle PagingCycle, + ran-NotificationAreaInfo RAN-NotificationAreaInfo OPTIONAL, -- Need M + t380 PeriodicRNAU-TimerValue OPTIONAL, -- Need R + nextHopChainingCount NextHopChainingCount, + ... +} + + +PeriodicRNAU-TimerValue ::= ENUMERATED { min5, min10, min20, min30, min60, min120, min360, min720} + + +CellReselectionPriorities ::= SEQUENCE { + freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need M + freqPriorityListNR FreqPriorityListNR OPTIONAL, -- Need M + t320 ENUMERATED {min5, min10, min20, min30, min60, min120, min180, spare1} OPTIONAL, -- Need R + ... +} + +PagingCycle ::= ENUMERATED {rf32, rf64, rf128, rf256} + +FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA + +FreqPriorityListNR ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityNR + +FreqPriorityEUTRA ::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + cellReselectionPriority CellReselectionPriority, + cellReselectionSubPriority CellReselectionSubPriority OPTIONAL -- Need R +} + +FreqPriorityNR ::= SEQUENCE { + carrierFreq ARFCN-ValueNR, + cellReselectionPriority CellReselectionPriority, + cellReselectionSubPriority CellReselectionSubPriority OPTIONAL -- Need R +} + +RAN-NotificationAreaInfo ::= CHOICE { + cellList PLMN-RAN-AreaCellList, + ran-AreaConfigList PLMN-RAN-AreaConfigList, + ... +} + +PLMN-RAN-AreaCellList ::= SEQUENCE (SIZE (1.. maxPLMNIdentities)) OF PLMN-RAN-AreaCell + +PLMN-RAN-AreaCell ::= SEQUENCE { + plmn-Identity PLMN-Identity OPTIONAL, -- Need S + ran-AreaCells SEQUENCE (SIZE (1..32)) OF CellIdentity +} + +PLMN-RAN-AreaConfigList ::= SEQUENCE (SIZE (1..maxPLMNIdentities)) OF PLMN-RAN-AreaConfig + +PLMN-RAN-AreaConfig ::= SEQUENCE { + plmn-Identity PLMN-Identity OPTIONAL, -- Need S + ran-Area SEQUENCE (SIZE (1..16)) OF RAN-AreaConfig +} + +RAN-AreaConfig ::= SEQUENCE { + trackingAreaCode TrackingAreaCode, + ran-AreaCodeList SEQUENCE (SIZE (1..32)) OF RAN-AreaCode OPTIONAL -- Need R +} + +-- TAG-RRCRELEASE-STOP +-- TAG-RRCRESUME-START + +RRCResume ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcResume RRCResume-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCResume-IEs ::= SEQUENCE { + radioBearerConfig RadioBearerConfig OPTIONAL, -- Need M + masterCellGroup OCTET STRING (CONTAINING CellGroupConfig) OPTIONAL, -- Need M + measConfig MeasConfig OPTIONAL, -- Need M + fullConfig ENUMERATED {true} OPTIONAL, -- Need N + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCResume-v1560-IEs OPTIONAL +} + +RRCResume-v1560-IEs ::= SEQUENCE { + radioBearerConfig2 OCTET STRING (CONTAINING RadioBearerConfig) OPTIONAL, -- Need M + sk-Counter SK-Counter OPTIONAL, -- Need N + nonCriticalExtension RRCResume-v1610-IEs OPTIONAL +} + +RRCResume-v1610-IEs ::= SEQUENCE { + idleModeMeasurementReq-r16 ENUMERATED {true} OPTIONAL, -- Need N + restoreMCG-SCells-r16 ENUMERATED {true} OPTIONAL, -- Need N + restoreSCG-r16 ENUMERATED {true} OPTIONAL, -- Need N + mrdc-SecondaryCellGroup-r16 CHOICE { + nr-SCG-r16 OCTET STRING (CONTAINING RRCReconfiguration), + eutra-SCG-r16 OCTET STRING + } OPTIONAL, -- Cond RestoreSCG + needForGapsConfigNR-r16 SetupRelease {NeedForGapsConfigNR-r16} OPTIONAL, -- Need M + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-RRCRESUME-STOP +-- TAG-RRCRESUMECOMPLETE-START + +RRCResumeComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcResumeComplete RRCResumeComplete-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCResumeComplete-IEs ::= SEQUENCE { + dedicatedNAS-Message DedicatedNAS-Message OPTIONAL, + selectedPLMN-Identity INTEGER (1..maxPLMN) OPTIONAL, + uplinkTxDirectCurrentList UplinkTxDirectCurrentList OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCResumeComplete-v1610-IEs OPTIONAL +} + +RRCResumeComplete-v1610-IEs ::= SEQUENCE { + idleMeasAvailable-r16 ENUMERATED {true} OPTIONAL, + measResultIdleEUTRA-r16 MeasResultIdleEUTRA-r16 OPTIONAL, + measResultIdleNR-r16 MeasResultIdleNR-r16 OPTIONAL, + scg-Response-r16 CHOICE { + nr-SCG-Response OCTET STRING (CONTAINING RRCReconfigurationComplete), + eutra-SCG-Response OCTET STRING + } OPTIONAL, + ueMeasurementsAvailable-r16 UEMeasurementsAvailable-r16 OPTIONAL, + mobilityHistoryAvail-r16 ENUMERATED {true} OPTIONAL, + mobilityState-r16 ENUMERATED {normal, medium, high, spare} OPTIONAL, + needForGapsInfoNR-r16 NeedForGapsInfoNR-r16 OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-RRCRESUMECOMPLETE-STOP +-- TAG-RRCRESUMEREQUEST-START + +RRCResumeRequest ::= SEQUENCE { + rrcResumeRequest RRCResumeRequest-IEs +} + +RRCResumeRequest-IEs ::= SEQUENCE { + resumeIdentity ShortI-RNTI-Value, + resumeMAC-I BIT STRING (SIZE (16)), + resumeCause ResumeCause, + spare BIT STRING (SIZE (1)) +} + +-- TAG-RRCRESUMEREQUEST-STOP +-- TAG-RRCRESUMEREQUEST1-START + +RRCResumeRequest1 ::= SEQUENCE { + rrcResumeRequest1 RRCResumeRequest1-IEs +} + +RRCResumeRequest1-IEs ::= SEQUENCE { + resumeIdentity I-RNTI-Value, + resumeMAC-I BIT STRING (SIZE (16)), + resumeCause ResumeCause, + spare BIT STRING (SIZE (1)) +} + +-- TAG-RRCRESUMEREQUEST1-STOP +-- TAG-RRCSETUP-START + +RRCSetup ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcSetup RRCSetup-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCSetup-IEs ::= SEQUENCE { + radioBearerConfig RadioBearerConfig, + masterCellGroup OCTET STRING (CONTAINING CellGroupConfig), + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-RRCSETUP-STOP +-- TAG-RRCSETUPCOMPLETE-START + +RRCSetupComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + rrcSetupComplete RRCSetupComplete-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +RRCSetupComplete-IEs ::= SEQUENCE { + selectedPLMN-Identity INTEGER (1..maxPLMN), + registeredAMF RegisteredAMF OPTIONAL, + guami-Type ENUMERATED {native, mapped} OPTIONAL, + s-NSSAI-List SEQUENCE (SIZE (1..maxNrofS-NSSAI)) OF S-NSSAI OPTIONAL, + dedicatedNAS-Message DedicatedNAS-Message, + ng-5G-S-TMSI-Value CHOICE { + ng-5G-S-TMSI NG-5G-S-TMSI, + ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9)) + } OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension RRCSetupComplete-v1610-IEs OPTIONAL +} + +RRCSetupComplete-v1610-IEs ::= SEQUENCE { + iab-NodeIndication-r16 ENUMERATED {true} OPTIONAL, + idleMeasAvailable-r16 ENUMERATED {true} OPTIONAL, + ueMeasurementsAvailable-r16 UEMeasurementsAvailable-r16 OPTIONAL, + mobilityHistoryAvail-r16 ENUMERATED {true} OPTIONAL, + mobilityState-r16 ENUMERATED {normal, medium, high, spare} OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +RegisteredAMF ::= SEQUENCE { + plmn-Identity PLMN-Identity OPTIONAL, + amf-Identifier AMF-Identifier +} + +-- TAG-RRCSETUPCOMPLETE-STOP +-- TAG-RRCSETUPREQUEST-START + +RRCSetupRequest ::= SEQUENCE { + rrcSetupRequest RRCSetupRequest-IEs +} + +RRCSetupRequest-IEs ::= SEQUENCE { + ue-Identity InitialUE-Identity, + establishmentCause EstablishmentCause, + spare BIT STRING (SIZE (1)) +} + +InitialUE-Identity ::= CHOICE { + ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)), + randomValue BIT STRING (SIZE (39)) +} + +EstablishmentCause ::= ENUMERATED { + emergency, highPriorityAccess, mt-Access, mo-Signalling, + mo-Data, mo-VoiceCall, mo-VideoCall, mo-SMS, mps-PriorityAccess, mcs-PriorityAccess, + spare6, spare5, spare4, spare3, spare2, spare1} + +-- TAG-RRCSETUPREQUEST-STOP +-- TAG-RRCSYSTEMINFOREQUEST-START + +RRCSystemInfoRequest ::= SEQUENCE { + criticalExtensions CHOICE { + rrcSystemInfoRequest RRCSystemInfoRequest-IEs, + criticalExtensionsFuture-r16 CHOICE { + rrcPosSystemInfoRequest-r16 RRC-PosSystemInfoRequest-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } + } +} + +RRCSystemInfoRequest-IEs ::= SEQUENCE { + requested-SI-List BIT STRING (SIZE (maxSI-Message)), --32bits + spare BIT STRING (SIZE (12)) +} + +RRC-PosSystemInfoRequest-r16-IEs ::= SEQUENCE { + requestedPosSI-List BIT STRING (SIZE (maxSI-Message)), --32bits + spare BIT STRING (SIZE (11)) +} + +-- TAG-RRCSYSTEMINFOREQUEST-STOP +-- TAG-SCGFAILUREINFORMATION-START + +SCGFailureInformation ::= SEQUENCE { + criticalExtensions CHOICE { + scgFailureInformation SCGFailureInformation-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SCGFailureInformation-IEs ::= SEQUENCE { + failureReportSCG FailureReportSCG OPTIONAL, + nonCriticalExtension SCGFailureInformation-v1590-IEs OPTIONAL +} + +SCGFailureInformation-v1590-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +FailureReportSCG ::= SEQUENCE { + failureType ENUMERATED { + t310-Expiry, randomAccessProblem, + rlc-MaxNumRetx, + synchReconfigFailureSCG, scg-ReconfigFailure, + srb3-IntegrityFailure, other-r16, spare1}, + measResultFreqList MeasResultFreqList OPTIONAL, + measResultSCG-Failure OCTET STRING (CONTAINING MeasResultSCG-Failure) OPTIONAL, + ..., + [[ + locationInfo-r16 LocationInfo-r16 OPTIONAL, + failureType-v1610 ENUMERATED {scg-lbtFailure-r16, beamFailureRecoveryFailure-r16, t312-Expiry-r16, bh-RLF-r16, + spare4, spare3, spare2, spare1} OPTIONAL + ]] +} + +MeasResultFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2NR + + +-- TAG-SCGFAILUREINFORMATION-STOP +-- TAG-SCGFAILUREINFORMATIONEUTRA-START + +SCGFailureInformationEUTRA ::= SEQUENCE { + criticalExtensions CHOICE { + scgFailureInformationEUTRA SCGFailureInformationEUTRA-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SCGFailureInformationEUTRA-IEs ::= SEQUENCE { + failureReportSCG-EUTRA FailureReportSCG-EUTRA OPTIONAL, + nonCriticalExtension SCGFailureInformationEUTRA-v1590-IEs OPTIONAL +} + +SCGFailureInformationEUTRA-v1590-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +FailureReportSCG-EUTRA ::= SEQUENCE { + failureType ENUMERATED { + t313-Expiry, randomAccessProblem, + rlc-MaxNumRetx, scg-ChangeFailure, + scg-lbtFailure-r16, beamFailureRecoveryFailure-r16, + t312-Expiry-r16, spare}, + measResultFreqListMRDC MeasResultFreqListFailMRDC OPTIONAL, + measResultSCG-FailureMRDC OCTET STRING OPTIONAL, + ..., + [[ + locationInfo-r16 LocationInfo-r16 OPTIONAL + ]] +} + +MeasResultFreqListFailMRDC ::= SEQUENCE (SIZE (1.. maxFreq)) OF MeasResult2EUTRA + +-- TAG-SCGFAILUREINFORMATIONEUTRA-STOP +-- TAG-SECURITYMODECOMMAND-START + +SecurityModeCommand ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + securityModeCommand SecurityModeCommand-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SecurityModeCommand-IEs ::= SEQUENCE { + securityConfigSMC SecurityConfigSMC, + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +SecurityConfigSMC ::= SEQUENCE { + securityAlgorithmConfig SecurityAlgorithmConfig, + ... +} + +-- TAG-SECURITYMODECOMMAND-STOP +-- TAG-SECURITYMODECOMPLETE-START + +SecurityModeComplete ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + securityModeComplete SecurityModeComplete-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SecurityModeComplete-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-SECURITYMODECOMPLETE-STOP +-- TAG-SECURITYMODEFAILURE-START + +SecurityModeFailure ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + securityModeFailure SecurityModeFailure-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SecurityModeFailure-IEs ::= SEQUENCE { + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-SECURITYMODEFAILURE-STOP +-- TAG-SIB1-START + +SIB1 ::= SEQUENCE { + cellSelectionInfo SEQUENCE { + q-RxLevMin Q-RxLevMin, + q-RxLevMinOffset INTEGER (1..8) OPTIONAL, -- Need S + q-RxLevMinSUL Q-RxLevMin OPTIONAL, -- Need R + q-QualMin Q-QualMin OPTIONAL, -- Need S + q-QualMinOffset INTEGER (1..8) OPTIONAL -- Need S + } OPTIONAL, -- Cond Standalone + cellAccessRelatedInfo CellAccessRelatedInfo, + connEstFailureControl ConnEstFailureControl OPTIONAL, -- Need R + si-SchedulingInfo SI-SchedulingInfo OPTIONAL, -- Need R + servingCellConfigCommon ServingCellConfigCommonSIB OPTIONAL, -- Need R + ims-EmergencySupport ENUMERATED {true} OPTIONAL, -- Need R + eCallOverIMS-Support ENUMERATED {true} OPTIONAL, -- Need R + ue-TimersAndConstants UE-TimersAndConstants OPTIONAL, -- Need R + uac-BarringInfo SEQUENCE { + uac-BarringForCommon UAC-BarringPerCatList OPTIONAL, -- Need S + uac-BarringPerPLMN-List UAC-BarringPerPLMN-List OPTIONAL, -- Need S + uac-BarringInfoSetList UAC-BarringInfoSetList, + uac-AccessCategory1-SelectionAssistanceInfo CHOICE { + plmnCommon UAC-AccessCategory1-SelectionAssistanceInfo, + individualPLMNList SEQUENCE (SIZE (2..maxPLMN)) OF UAC-AccessCategory1-SelectionAssistanceInfo + } OPTIONAL -- Need S + } OPTIONAL, -- Need R + useFullResumeID ENUMERATED {true} OPTIONAL, -- Need R + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SIB1-v1610-IEs OPTIONAL +} + +SIB1-v1610-IEs ::= SEQUENCE { + idleModeMeasurementsEUTRA-r16 ENUMERATED{true} OPTIONAL, -- Need R + idleModeMeasurementsNR-r16 ENUMERATED{true} OPTIONAL, -- Need R + posSI-SchedulingInfo-r16 PosSI-SchedulingInfo-r16 OPTIONAL, -- Need R + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +UAC-AccessCategory1-SelectionAssistanceInfo ::= ENUMERATED {a, b, c} + +-- TAG-SIB1-STOP +-- TAG-SIDELINKUEINFORMATIONNR-START + +SidelinkUEInformationNR-r16::= SEQUENCE { + criticalExtensions CHOICE { + sidelinkUEInformationNR-r16 SidelinkUEInformationNR-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +SidelinkUEInformationNR-r16-IEs ::= SEQUENCE { + sl-RxInterestedFreqList-r16 SL-InterestedFreqList-r16 OPTIONAL, + sl-TxResourceReqList-r16 SL-TxResourceReqList-r16 OPTIONAL, + sl-FailureList-r16 SL-FailureList-r16 OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +SL-InterestedFreqList-r16 ::= SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF INTEGER (1..maxNrofFreqSL-r16) + +SL-TxResourceReqList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-Dest-r16)) OF SL-TxResourceReq-r16 + +SL-TxResourceReq-r16 ::= SEQUENCE { + sl-DestinationIdentity-r16 SL-DestinationIdentity-r16, + sl-CastType-r16 ENUMERATED {broadcast, groupcast, unicast, spare1}, + sl-RLC-ModeIndicationList-r16 SEQUENCE (SIZE (1.. maxNrofSLRB-r16)) OF SL-RLC-ModeIndication-r16 OPTIONAL, + sl-QoS-InfoList-r16 SEQUENCE (SIZE (1..maxNrofSL-QFIsPerDest-r16)) OF SL-QoS-Info-r16 OPTIONAL, + sl-TypeTxSyncList-r16 SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF SL-TypeTxSync-r16 OPTIONAL, + sl-TxInterestedFreqList-r16 SL-TxInterestedFreqList-r16 OPTIONAL, + sl-CapabilityInformationSidelink-r16 OCTET STRING OPTIONAL +} + +SL-TxInterestedFreqList-r16 ::= SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF INTEGER (1..maxNrofFreqSL-r16) + +SL-QoS-Info-r16 ::= SEQUENCE { + sl-QoS-FlowIdentity-r16 SL-QoS-FlowIdentity-r16, + sl-QoS-Profile-r16 SL-QoS-Profile-r16 OPTIONAL +} + +SL-RLC-ModeIndication-r16 ::= SEQUENCE { + sl-Mode-r16 CHOICE { + sl-AM-Mode-r16 NULL, + sl-UM-Mode-r16 NULL + }, + sl-QoS-InfoList-r16 SEQUENCE (SIZE (1..maxNrofSL-QFIsPerDest-r16)) OF SL-QoS-Info-r16 +} + +SL-FailureList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-Dest-r16)) OF SL-Failure-r16 + +SL-Failure-r16 ::= SEQUENCE { + sl-DestinationIdentity-r16 SL-DestinationIdentity-r16, + sl-Failure-r16 ENUMERATED {rlf,configFailure, spare6, spare5, spare4, spare3, spare2, spare1} +} + +-- TAG-SIDELINKUEINFORMATIONNR-STOP +-- TAG-SYSTEMINFORMATION-START + +SystemInformation ::= SEQUENCE { + criticalExtensions CHOICE { + systemInformation SystemInformation-IEs, + criticalExtensionsFuture-r16 CHOICE { + posSystemInformation-r16 PosSystemInformation-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } + } +} + +SystemInformation-IEs ::= SEQUENCE { + sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE { + sib2 SIB2, + sib3 SIB3, + sib4 SIB4, + sib5 SIB5, + sib6 SIB6, + sib7 SIB7, + sib8 SIB8, + sib9 SIB9, + ..., + sib10-v1610 SIB10-r16, + sib11-v1610 SIB11-r16, + sib12-v1610 SIB12-r16, + sib13-v1610 SIB13-r16, + sib14-v1610 SIB14-r16 + }, + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-SYSTEMINFORMATION-STOP +-- TAG-UEASSISTANCEINFORMATION-START + +UEAssistanceInformation ::= SEQUENCE { + criticalExtensions CHOICE { + ueAssistanceInformation UEAssistanceInformation-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEAssistanceInformation-IEs ::= SEQUENCE { + delayBudgetReport DelayBudgetReport OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UEAssistanceInformation-v1540-IEs OPTIONAL +} + +DelayBudgetReport::= CHOICE { + type1 ENUMERATED { + msMinus1280, msMinus640, msMinus320, msMinus160,msMinus80, msMinus60, msMinus40, + msMinus20, ms0, ms20,ms40, ms60, ms80, ms160, ms320, ms640, ms1280}, + ... +} + +UEAssistanceInformation-v1540-IEs ::= SEQUENCE { + overheatingAssistance OverheatingAssistance OPTIONAL, + nonCriticalExtension UEAssistanceInformation-v1610-IEs OPTIONAL +} + +OverheatingAssistance ::= SEQUENCE { + reducedMaxCCs ReducedMaxCCs-r16 OPTIONAL, + reducedMaxBW-FR1 ReducedMaxBW-FRx-r16 OPTIONAL, + reducedMaxBW-FR2 ReducedMaxBW-FRx-r16 OPTIONAL, + reducedMaxMIMO-LayersFR1 SEQUENCE { + reducedMIMO-LayersFR1-DL MIMO-LayersDL, + reducedMIMO-LayersFR1-UL MIMO-LayersUL + } OPTIONAL, + reducedMaxMIMO-LayersFR2 SEQUENCE { + reducedMIMO-LayersFR2-DL MIMO-LayersDL, + reducedMIMO-LayersFR2-UL MIMO-LayersUL + } OPTIONAL +} + +ReducedAggregatedBandwidth ::= ENUMERATED {mhz0, mhz10, mhz20, mhz30, mhz40, mhz50, mhz60, mhz80, mhz100, mhz200, mhz300, mhz400} + +UEAssistanceInformation-v1610-IEs ::= SEQUENCE { + idc-Assistance-r16 IDC-Assistance-r16 OPTIONAL, + drx-Preference-r16 DRX-Preference-r16 OPTIONAL, + maxBW-Preference-r16 MaxBW-Preference-r16 OPTIONAL, + maxCC-Preference-r16 MaxCC-Preference-r16 OPTIONAL, + maxMIMO-LayerPreference-r16 MaxMIMO-LayerPreference-r16 OPTIONAL, + minSchedulingOffsetPreference-r16 MinSchedulingOffsetPreference-r16 OPTIONAL, + releasePreference-r16 ReleasePreference-r16 OPTIONAL, + sl-UE-AssistanceInformationNR-r16 SL-UE-AssistanceInformationNR-r16 OPTIONAL, + referenceTimeInfoPreference-r16 BOOLEAN OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +IDC-Assistance-r16 ::= SEQUENCE { + affectedCarrierFreqList-r16 AffectedCarrierFreqList-r16 OPTIONAL, + affectedCarrierFreqCombList-r16 AffectedCarrierFreqCombList-r16 OPTIONAL, + ... +} + +AffectedCarrierFreqList-r16 ::= SEQUENCE (SIZE (1.. maxFreqIDC-r16)) OF AffectedCarrierFreq-r16 + +AffectedCarrierFreq-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueNR, + interferenceDirection-r16 ENUMERATED {nr, other, both, spare} +} + +AffectedCarrierFreqCombList-r16 ::= SEQUENCE (SIZE (1..maxCombIDC-r16)) OF AffectedCarrierFreqComb-r16 + +AffectedCarrierFreqComb-r16 ::= SEQUENCE { + affectedCarrierFreqComb-r16 SEQUENCE (SIZE (2..maxNrofServingCells)) OF ARFCN-ValueNR OPTIONAL, + victimSystemType-r16 VictimSystemType-r16 +} + +VictimSystemType-r16 ::= SEQUENCE { + gps-r16 ENUMERATED {true} OPTIONAL, + glonass-r16 ENUMERATED {true} OPTIONAL, + bds-r16 ENUMERATED {true} OPTIONAL, + galileo-r16 ENUMERATED {true} OPTIONAL, + navIC-r16 ENUMERATED {true} OPTIONAL, + wlan-r16 ENUMERATED {true} OPTIONAL, + bluetooth-r16 ENUMERATED {true} OPTIONAL, + ... +} + +DRX-Preference-r16 ::= SEQUENCE { + preferredDRX-InactivityTimer-r16 ENUMERATED { + ms0, ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40, ms50, ms60, ms80, + ms100, ms200, ms300, ms500, ms750, ms1280, ms1920, ms2560, spare9, spare8, + spare7, spare6, spare5, spare4, spare3, spare2, spare1} OPTIONAL, + preferredDRX-LongCycle-r16 ENUMERATED { + ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, + ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, spare12, spare11, spare10, + spare9, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 } OPTIONAL, + preferredDRX-ShortCycle-r16 ENUMERATED { + ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, + ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, spare9, + spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 } OPTIONAL, + preferredDRX-ShortCycleTimer-r16 INTEGER (1..16) OPTIONAL +} + +MaxBW-Preference-r16 ::= SEQUENCE { + reducedMaxBW-FR1-r16 ReducedMaxBW-FRx-r16 OPTIONAL, + reducedMaxBW-FR2-r16 ReducedMaxBW-FRx-r16 OPTIONAL +} + +MaxCC-Preference-r16 ::= SEQUENCE { + reducedMaxCCs-r16 ReducedMaxCCs-r16 OPTIONAL +} + +MaxMIMO-LayerPreference-r16 ::= SEQUENCE { + reducedMaxMIMO-LayersFR1-r16 SEQUENCE { + reducedMIMO-LayersFR1-DL-r16 INTEGER (1..8), + reducedMIMO-LayersFR1-UL-r16 INTEGER (1..4) + } OPTIONAL, + reducedMaxMIMO-LayersFR2-r16 SEQUENCE { + reducedMIMO-LayersFR2-DL-r16 INTEGER (1..8), + reducedMIMO-LayersFR2-UL-r16 INTEGER (1..4) + } OPTIONAL +} + +MinSchedulingOffsetPreference-r16 ::= SEQUENCE { + preferredK0-r16 SEQUENCE { + preferredK0-SCS-15kHz-r16 ENUMERATED {sl1, sl2, sl4, sl6} OPTIONAL, + preferredK0-SCS-30kHz-r16 ENUMERATED {sl1, sl2, sl4, sl6} OPTIONAL, + preferredK0-SCS-60kHz-r16 ENUMERATED {sl2, sl4, sl8, sl12} OPTIONAL, + preferredK0-SCS-120kHz-r16 ENUMERATED {sl2, sl4, sl8, sl12} OPTIONAL + } OPTIONAL, + preferredK2-r16 SEQUENCE { + preferredK2-SCS-15kHz-r16 ENUMERATED {sl1, sl2, sl4, sl6} OPTIONAL, + preferredK2-SCS-30kHz-r16 ENUMERATED {sl1, sl2, sl4, sl6} OPTIONAL, + preferredK2-SCS-60kHz-r16 ENUMERATED {sl2, sl4, sl8, sl12} OPTIONAL, + preferredK2-SCS-120kHz-r16 ENUMERATED {sl2, sl4, sl8, sl12} OPTIONAL + } OPTIONAL +} + +ReleasePreference-r16 ::= SEQUENCE { + preferredRRC-State-r16 ENUMERATED {idle, inactive, connected, outOfConnected} +} + +ReducedMaxBW-FRx-r16 ::= SEQUENCE { + reducedBW-DL-r16 ReducedAggregatedBandwidth, + reducedBW-UL-r16 ReducedAggregatedBandwidth +} + +ReducedMaxCCs-r16 ::= SEQUENCE { + reducedCCsDL-r16 INTEGER (0..31), + reducedCCsUL-r16 INTEGER (0..31) +} + +SL-UE-AssistanceInformationNR-r16 ::= SEQUENCE (SIZE (1..maxNrofTrafficPattern-r16)) OF SL-TrafficPatternInfo-r16 + +SL-TrafficPatternInfo-r16::= SEQUENCE { + trafficPeriodicity-r16 ENUMERATED {ms20,ms50, ms100, ms200, ms300, ms400, ms500, ms600, ms700, ms800, ms900, ms1000}, + timingOffset-r16 INTEGER (0..10239), + messageSize-r16 BIT STRING (SIZE (8)), + sl-QoS-FlowIdentity-r16 SL-QoS-FlowIdentity-r16 +} + +-- TAG-UEASSISTANCEINFORMATION-STOP +-- TAG-UECAPABILITYENQUIRY-START + +UECapabilityEnquiry ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + ueCapabilityEnquiry UECapabilityEnquiry-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +UECapabilityEnquiry-IEs ::= SEQUENCE { + ue-CapabilityRAT-RequestList UE-CapabilityRAT-RequestList, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ue-CapabilityEnquiryExt OCTET STRING (CONTAINING UECapabilityEnquiry-v1560-IEs) OPTIONAL +} + +UECapabilityEnquiry-v1560-IEs ::= SEQUENCE { + capabilityRequestFilterCommon UE-CapabilityRequestFilterCommon OPTIONAL, -- Need N + nonCriticalExtension UECapabilityEnquiry-v1610-IEs OPTIONAL +} + +UECapabilityEnquiry-v1610-IEs ::= SEQUENCE { + rrc-SegAllowed-r16 ENUMERATED {enabled} OPTIONAL, -- Need N + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-UECAPABILITYENQUIRY-STOP +-- TAG-UECAPABILITYINFORMATION-START + +UECapabilityInformation ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + ueCapabilityInformation UECapabilityInformation-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +UECapabilityInformation-IEs ::= SEQUENCE { + ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList OPTIONAL, + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE{} OPTIONAL +} + +-- TAG-UECAPABILITYINFORMATION-STOP +-- TAG-UEINFORMATIONREQUEST-START + +UEInformationRequest-r16 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + ueInformationRequest-r16 UEInformationRequest-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEInformationRequest-r16-IEs ::= SEQUENCE { + idleModeMeasurementReq-r16 ENUMERATED{true} OPTIONAL, -- Need N + logMeasReportReq-r16 ENUMERATED {true} OPTIONAL, -- Need N + connEstFailReportReq-r16 ENUMERATED {true} OPTIONAL, -- Need N + ra-ReportReq-r16 ENUMERATED {true} OPTIONAL, -- Need N + rlf-ReportReq-r16 ENUMERATED {true} OPTIONAL, -- Need N + mobilityHistoryReportReq-r16 ENUMERATED {true} OPTIONAL, -- Need N + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-UEINFORMATIONREQUEST-STOP +-- TAG-UEINFORMATIONRESPONSE-START + +UEInformationResponse-r16 ::= SEQUENCE { + rrc-TransactionIdentifier RRC-TransactionIdentifier, + criticalExtensions CHOICE { + ueInformationResponse-r16 UEInformationResponse-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +UEInformationResponse-r16-IEs ::= SEQUENCE { + measResultIdleEUTRA-r16 MeasResultIdleEUTRA-r16 OPTIONAL, + measResultIdleNR-r16 MeasResultIdleNR-r16 OPTIONAL, + logMeasReport-r16 LogMeasReport-r16 OPTIONAL, + connEstFailReport-r16 ConnEstFailReport-r16 OPTIONAL, + ra-ReportList-r16 RA-ReportList-r16 OPTIONAL, + rlf-Report-r16 RLF-Report-r16 OPTIONAL, + mobilityHistoryReport-r16 MobilityHistoryReport-r16 OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +LogMeasReport-r16 ::= SEQUENCE { + absoluteTimeStamp-r16 AbsoluteTimeInfo-r16, + traceReference-r16 TraceReference-r16, + traceRecordingSessionRef-r16 OCTET STRING (SIZE (2)), + tce-Id-r16 OCTET STRING (SIZE (1)), + logMeasInfoList-r16 LogMeasInfoList-r16, + logMeasAvailable-r16 ENUMERATED {true} OPTIONAL, + logMeasAvailableBT-r16 ENUMERATED {true} OPTIONAL, + logMeasAvailableWLAN-r16 ENUMERATED {true} OPTIONAL, + ... +} + +LogMeasInfoList-r16 ::= SEQUENCE (SIZE (1..maxLogMeasReport-r16)) OF LogMeasInfo-r16 + +LogMeasInfo-r16 ::= SEQUENCE { + locationInfo-r16 LocationInfo-r16 OPTIONAL, + relativeTimeStamp-r16 INTEGER (0..7200), + servCellIdentity-r16 CGI-Info-Logging-r16 OPTIONAL, + measResultServingCell-r16 MeasResultServingCell-r16 OPTIONAL, + measResultNeighCells-r16 SEQUENCE { + measResultNeighCellListNR MeasResultListLogging2NR-r16 OPTIONAL, + measResultNeighCellListEUTRA MeasResultList2EUTRA-r16 OPTIONAL + }, + anyCellSelectionDetected-r16 ENUMERATED {true} OPTIONAL +} + +ConnEstFailReport-r16 ::= SEQUENCE { + measResultFailedCell-r16 MeasResultFailedCell-r16, + locationInfo-r16 LocationInfo-r16 OPTIONAL, + measResultNeighCells-r16 SEQUENCE { + measResultNeighCellListNR MeasResultList2NR-r16 OPTIONAL, + measResultNeighCellListEUTRA MeasResultList2EUTRA-r16 OPTIONAL + }, + numberOfConnFail-r16 INTEGER (1..8), + perRAInfoList-r16 PerRAInfoList-r16, + timeSinceFailure-r16 TimeSinceFailure-r16, + ... +} + +MeasResultServingCell-r16 ::= SEQUENCE { + resultsSSB-Cell MeasQuantityResults, + resultsSSB SEQUENCE{ + best-ssb-Index SSB-Index, + best-ssb-Results MeasQuantityResults, + numberOfGoodSSB INTEGER (1..maxNrofSSBs-r16) + } OPTIONAL +} + +MeasResultFailedCell-r16 ::= SEQUENCE { + cgi-Info CGI-Info-Logging-r16, + measResult-r16 SEQUENCE { + cellResults-r16 SEQUENCE{ + resultsSSB-Cell-r16 MeasQuantityResults + }, + rsIndexResults-r16 SEQUENCE{ + resultsSSB-Indexes-r16 ResultsPerSSB-IndexList + } + } +} + +RA-ReportList-r16 ::= SEQUENCE (SIZE (1..maxRAReport-r16)) OF RA-Report-r16 + +RA-Report-r16 ::= SEQUENCE { + cellId-r16 CGI-Info-Logging-r16, + ra-InformationCommon-r16 RA-InformationCommon-r16, + raPurpose-r16 ENUMERATED {accessRelated, beamFailureRecovery, reconfigurationWithSync, ulUnSynchronized, + schedulingRequestFailure, noPUCCHResourceAvailable, requestForOtherSI, + spare9, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1} +} + +RA-InformationCommon-r16 ::= SEQUENCE { + absoluteFrequencyPointA-r16 ARFCN-ValueNR, + locationAndBandwidth-r16 INTEGER (0..37949), + subcarrierSpacing-r16 SubcarrierSpacing, + msg1-FrequencyStart-r16 INTEGER (0..maxNrofPhysicalResourceBlocks-1) OPTIONAL, + msg1-FrequencyStartCFRA-r16 INTEGER (0..maxNrofPhysicalResourceBlocks-1) OPTIONAL, + msg1-SubcarrierSpacing-r16 SubcarrierSpacing OPTIONAL, + msg1-SubcarrierSpacingCFRA-r16 SubcarrierSpacing OPTIONAL, + msg1-FDM-r16 ENUMERATED {one, two, four, eight} OPTIONAL, + msg1-FDMCFRA-r16 ENUMERATED {one, two, four, eight} OPTIONAL, + perRAInfoList-r16 PerRAInfoList-r16 +} + +PerRAInfoList-r16 ::= SEQUENCE (SIZE (1..200)) OF PerRAInfo-r16 + +PerRAInfo-r16 ::= CHOICE { + perRASSBInfoList-r16 PerRASSBInfo-r16, + perRACSI-RSInfoList-r16 PerRACSI-RSInfo-r16 +} + +PerRASSBInfo-r16 ::= SEQUENCE { + ssb-Index-r16 SSB-Index, + numberOfPreamblesSentOnSSB-r16 INTEGER (1..200), + perRAAttemptInfoList-r16 PerRAAttemptInfoList-r16 +} + +PerRACSI-RSInfo-r16 ::= SEQUENCE { + csi-RS-Index-r16 CSI-RS-Index, + numberOfPreamblesSentOnCSI-RS-r16 INTEGER (1..200) +} + +PerRAAttemptInfoList-r16 ::= SEQUENCE (SIZE (1..200)) OF PerRAAttemptInfo-r16 + +PerRAAttemptInfo-r16 ::= SEQUENCE { + contentionDetected-r16 BOOLEAN OPTIONAL, + dlRSRPAboveThreshold-r16 BOOLEAN OPTIONAL, + ... +} + +RLF-Report-r16 ::= CHOICE { + nr-RLF-Report-r16 SEQUENCE { + measResultLastServCell-r16 MeasResultRLFNR-r16, + measResultNeighCells-r16 SEQUENCE { + measResultListNR-r16 MeasResultList2NR-r16 OPTIONAL, + measResultListEUTRA-r16 MeasResultList2EUTRA-r16 OPTIONAL + } OPTIONAL, + c-RNTI-r16 RNTI-Value, + previousPCellId-r16 CHOICE { + nrPreviousCell-r16 CGI-Info-Logging-r16, + eutraPreviousCell-r16 CGI-InfoEUTRALogging + } OPTIONAL, + failedPCellId-r16 CHOICE { + nrFailedPCellId-r16 CHOICE { + cellGlobalId-r16 CGI-Info-Logging-r16, + pci-arfcn-r16 SEQUENCE { + physCellId-r16 PhysCellId, + carrierFreq-r16 ARFCN-ValueNR + } + }, + eutraFailedPCellId-r16 CHOICE { + cellGlobalId-r16 CGI-InfoEUTRALogging, + pci-arfcn-r16 SEQUENCE { + physCellId-r16 EUTRA-PhysCellId, + carrierFreq-r16 ARFCN-ValueEUTRA + } + } + }, + reconnectCellId-r16 CHOICE { + nrReconnectCellId-r16 CGI-Info-Logging-r16, + eutraReconnectCellId-r16 CGI-InfoEUTRALogging + } OPTIONAL, + timeUntilReconnection-16 TimeUntilReconnection-16 OPTIONAL, + reestablishmentCellId-r16 CGI-Info-Logging-r16 OPTIONAL, + timeConnFailure-r16 INTEGER (0..1023) OPTIONAL, + timeSinceFailure-r16 TimeSinceFailure-r16, + connectionFailureType-r16 ENUMERATED {rlf, hof}, + rlf-Cause-r16 ENUMERATED {t310-Expiry, randomAccessProblem, rlc-MaxNumRetx, + beamFailureRecoveryFailure, lbtFailure-r16, + bh-rlfRecoveryFailure, spare2, spare1}, + locationInfo-r16 LocationInfo-r16 OPTIONAL, + noSuitableCellFound-r16 ENUMERATED {true} OPTIONAL, + ra-InformationCommon-r16 RA-InformationCommon-r16 OPTIONAL + }, + eutra-RLF-Report-r16 SEQUENCE { + failedPCellId-EUTRA CGI-InfoEUTRALogging, + measResult-RLF-Report-EUTRA-r16 OCTET STRING + } +} + +MeasResultList2NR-r16 ::= SEQUENCE(SIZE (1..maxFreq)) OF MeasResult2NR-r16 +MeasResultList2EUTRA-r16 ::= SEQUENCE(SIZE (1..maxFreq)) OF MeasResult2EUTRA-r16 + +MeasResult2NR-r16 ::= SEQUENCE { + ssbFrequency-r16 ARFCN-ValueNR OPTIONAL, + refFreqCSI-RS-r16 ARFCN-ValueNR OPTIONAL, + measResultList-r16 MeasResultListNR +} + +MeasResultListLogging2NR-r16 ::= SEQUENCE(SIZE (1..maxFreq)) OF MeasResultListLoggingNR-r16 + +MeasResultLogging2NR-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueNR, + measResultListLoggingNR-r16 MeasResultListLoggingNR-r16 +} + +MeasResultListLoggingNR-r16 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultLoggingNR-r16 + +MeasResultLoggingNR-r16 ::= SEQUENCE { + physCellId-r16 PhysCellId, + resultsSSB-Cell-r16 MeasQuantityResults, + numberOfGoodSSB-r16 INTEGER (1..maxNrofSSBs-r16) OPTIONAL +} + +MeasResult2EUTRA-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueEUTRA, + measResultList-r16 MeasResultListEUTRA +} + +MeasResultRLFNR-r16 ::= SEQUENCE { + measResult-r16 SEQUENCE { + cellResults-r16 SEQUENCE{ + resultsSSB-Cell-r16 MeasQuantityResults OPTIONAL, + resultsCSI-RS-Cell-r16 MeasQuantityResults OPTIONAL + }, + rsIndexResults-r16 SEQUENCE{ + resultsSSB-Indexes-r16 ResultsPerSSB-IndexList OPTIONAL, + ssbRLMConfigBitmap-r16 BIT STRING (SIZE (64)) OPTIONAL, + resultsCSI-RS-Indexes-r16 ResultsPerCSI-RS-IndexList OPTIONAL, + csi-rsRLMConfigBitmap-r16 BIT STRING (SIZE (96)) OPTIONAL + } OPTIONAL + } +} + +TimeSinceFailure-r16 ::= INTEGER (0..172800) + +MobilityHistoryReport-r16 ::= VisitedCellInfoList-r16 + +TimeUntilReconnection-16 ::= INTEGER (0..172800) + +-- TAG-UEINFORMATIONRESPONSE-STOP +-- TAG-ULDEDICATEDMESSAGESEGMENT-START + +ULDedicatedMessageSegment-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + ulDedicatedMessageSegment-r16 ULDedicatedMessageSegment-r16-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULDedicatedMessageSegment-r16-IEs ::= SEQUENCE { + segmentNumber-r16 INTEGER (0..15), + rrc-MessageSegmentContainer-r16 OCTET STRING, + rrc-MessageSegmentType-r16 ENUMERATED {notLastSegment, lastSegment}, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-ULDEDICATEDMESSAGESEGMENT-STOP +-- TAG-ULINFORMATIONTRANSFER-START + +ULInformationTransfer ::= SEQUENCE { + criticalExtensions CHOICE { + ulInformationTransfer ULInformationTransfer-IEs, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULInformationTransfer-IEs ::= SEQUENCE { + dedicatedNAS-Message DedicatedNAS-Message OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-ULINFORMATIONTRANSFER-STOP +-- TAG-ULINFORMATIONTRANSFERIRAT-START + +ULInformationTransferIRAT-r16 ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + ulInformationTransferIRAT-r16 ULInformationTransferIRAT-r16-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULInformationTransferIRAT-r16-IEs ::= SEQUENCE { + ul-DCCH-MessageEUTRA-r16 OCTET STRING OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-ULINFORMATIONTRANSFERIRAT-STOP +-- TAG-ULINFORMATIONTRANSFERMRDC-START + +ULInformationTransferMRDC ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE { + ulInformationTransferMRDC ULInformationTransferMRDC-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +ULInformationTransferMRDC-IEs::= SEQUENCE { + ul-DCCH-MessageNR OCTET STRING OPTIONAL, + ul-DCCH-MessageEUTRA OCTET STRING OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-ULINFORMATIONTRANSFERMRDC-STOP +-- TAG-SETUPRELEASE-START + +SetupRelease { ElementTypeParam } ::= CHOICE { + release NULL, + setup ElementTypeParam +} + +-- TAG-SETUPRELEASE-STOP +-- TAG-SIB2-START + +SIB2 ::= SEQUENCE { + cellReselectionInfoCommon SEQUENCE { + nrofSS-BlocksToAverage INTEGER (2..maxNrofSS-BlocksToAverage) OPTIONAL, -- Need S + absThreshSS-BlocksConsolidation ThresholdNR OPTIONAL, -- Need S + rangeToBestCell RangeToBestCell OPTIONAL, -- Need R + q-Hyst ENUMERATED { + dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, + dB12, dB14, dB16, dB18, dB20, dB22, dB24}, + speedStateReselectionPars SEQUENCE { + mobilityStateParameters MobilityStateParameters, + q-HystSF SEQUENCE { + sf-Medium ENUMERATED {dB-6, dB-4, dB-2, dB0}, + sf-High ENUMERATED {dB-6, dB-4, dB-2, dB0} + } + } OPTIONAL, -- Need R + ... + }, + cellReselectionServingFreqInfo SEQUENCE { + s-NonIntraSearchP ReselectionThreshold OPTIONAL, -- Need S + s-NonIntraSearchQ ReselectionThresholdQ OPTIONAL, -- Need S + threshServingLowP ReselectionThreshold, + threshServingLowQ ReselectionThresholdQ OPTIONAL, -- Need R + cellReselectionPriority CellReselectionPriority, + cellReselectionSubPriority CellReselectionSubPriority OPTIONAL, -- Need R + ... + }, + intraFreqCellReselectionInfo SEQUENCE { + q-RxLevMin Q-RxLevMin, + q-RxLevMinSUL Q-RxLevMin OPTIONAL, -- Need R + q-QualMin Q-QualMin OPTIONAL, -- Need S + s-IntraSearchP ReselectionThreshold, + s-IntraSearchQ ReselectionThresholdQ OPTIONAL, -- Need S + t-ReselectionNR T-Reselection, + frequencyBandList MultiFrequencyBandListNR-SIB OPTIONAL, -- Need S + frequencyBandListSUL MultiFrequencyBandListNR-SIB OPTIONAL, -- Need R + p-Max P-Max OPTIONAL, -- Need S + smtc SSB-MTC OPTIONAL, -- Need S + ss-RSSI-Measurement SS-RSSI-Measurement OPTIONAL, -- Need R + ssb-ToMeasure SSB-ToMeasure OPTIONAL, -- Need S + deriveSSB-IndexFromCell BOOLEAN, + ..., + [[ + t-ReselectionNR-SF SpeedStateScaleFactors OPTIONAL -- Need N + ]], + [[ + smtc2-LP-r16 SSB-MTC2-LP-r16 OPTIONAL, -- Need R + ssb-PositionQCL-Common-r16 SSB-PositionQCL-Relation-r16 OPTIONAL -- Cond SharedSpectrum + ]] + }, + ..., + [[ + relaxedMeasurement-r16 SEQUENCE { + lowMobilityEvaluation-r16 SEQUENCE { + s-SearchDeltaP-r16 ENUMERATED { + dB3, dB6, dB9, dB12, dB15, + spare3, spare2, spare1}, + t-SearchDeltaP-r16 ENUMERATED { + s5, s10, s20, s30, s60, s120, s180, + s240, s300, spare7, spare6, spare5, + spare4, spare3, spare2, spare1} + } OPTIONAL, -- Need R + cellEdgeEvaluation-r16 SEQUENCE { + s-SearchThresholdP-r16 ReselectionThreshold, + s-SearchThresholdQ-r16 ReselectionThresholdQ OPTIONAL -- Need R + } OPTIONAL, -- Need R + combineRelaxedMeasCondition-r16 ENUMERATED {true} OPTIONAL, -- Need R + highPriorityMeasRelax-r16 ENUMERATED {true} OPTIONAL -- Need R + } OPTIONAL -- Need R + ]] +} + +RangeToBestCell ::= Q-OffsetRange + +-- TAG-SIB2-STOP +-- TAG-SIB3-START + +SIB3 ::= SEQUENCE { + intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need R + intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need R + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + [[ + intraFreqNeighCellList-v1610 IntraFreqNeighCellList-v1610 OPTIONAL, -- Need R + intraFreqWhiteCellList-r16 IntraFreqWhiteCellList-r16 OPTIONAL, -- Cond SharedSpectrum2 + intraFreqCAG-CellList-r16 SEQUENCE (SIZE (1..maxPLMN)) OF IntraFreqCAG-CellPerPLMN-r16 OPTIONAL -- Need R + ]] +} + + +IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo + +IntraFreqNeighCellList-v1610::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo-v1610 + +IntraFreqNeighCellInfo ::= SEQUENCE { + physCellId PhysCellId, + q-OffsetCell Q-OffsetRange, + q-RxLevMinOffsetCell INTEGER (1..8) OPTIONAL, -- Need R + q-RxLevMinOffsetCellSUL INTEGER (1..8) OPTIONAL, -- Need R + q-QualMinOffsetCell INTEGER (1..8) OPTIONAL, -- Need R + ... +} + +IntraFreqNeighCellInfo-v1610 ::= SEQUENCE { + ssb-PositionQCL-r16 SSB-PositionQCL-Relation-r16 OPTIONAL -- Cond SharedSpectrum2 +} + +IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PCI-Range + +IntraFreqWhiteCellList-r16 ::= SEQUENCE (SIZE (1..maxCellWhite)) OF PCI-Range + +IntraFreqCAG-CellPerPLMN-r16 ::= SEQUENCE { + plmn-IdentityIndex-r16 INTEGER (1..maxPLMN), + cag-CellList-r16 SEQUENCE (SIZE (1..maxCAG-Cell-r16)) OF PCI-Range +} + +-- TAG-SIB3-STOP +-- TAG-SIB4-START + +SIB4 ::= SEQUENCE { + interFreqCarrierFreqList InterFreqCarrierFreqList, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + interFreqCarrierFreqList-v1610 InterFreqCarrierFreqList-v1610 OPTIONAL -- Need R +} + +InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo + +InterFreqCarrierFreqList-v1610 ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo-v1610 + +InterFreqCarrierFreqInfo ::= SEQUENCE { + dl-CarrierFreq ARFCN-ValueNR, + frequencyBandList MultiFrequencyBandListNR-SIB OPTIONAL, -- Cond Mandatory + frequencyBandListSUL MultiFrequencyBandListNR-SIB OPTIONAL, -- Need R + nrofSS-BlocksToAverage INTEGER (2..maxNrofSS-BlocksToAverage) OPTIONAL, -- Need S + absThreshSS-BlocksConsolidation ThresholdNR OPTIONAL, -- Need S + smtc SSB-MTC OPTIONAL, -- Need S + ssbSubcarrierSpacing SubcarrierSpacing, + ssb-ToMeasure SSB-ToMeasure OPTIONAL, -- Need S + deriveSSB-IndexFromCell BOOLEAN, + ss-RSSI-Measurement SS-RSSI-Measurement OPTIONAL, + q-RxLevMin Q-RxLevMin, + q-RxLevMinSUL Q-RxLevMin OPTIONAL, -- Need R + q-QualMin Q-QualMin OPTIONAL, -- Need S + p-Max P-Max OPTIONAL, -- Need S + t-ReselectionNR T-Reselection, + t-ReselectionNR-SF SpeedStateScaleFactors OPTIONAL, -- Need S + threshX-HighP ReselectionThreshold, + threshX-LowP ReselectionThreshold, + threshX-Q SEQUENCE { + threshX-HighQ ReselectionThresholdQ, + threshX-LowQ ReselectionThresholdQ + } OPTIONAL, -- Cond RSRQ + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need R + cellReselectionSubPriority CellReselectionSubPriority OPTIONAL, -- Need R + q-OffsetFreq Q-OffsetRange DEFAULT dB0, + interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need R + interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need R + ... +} + +InterFreqCarrierFreqInfo-v1610 ::= SEQUENCE { + interFreqNeighCellList-v1610 InterFreqNeighCellList-v1610 OPTIONAL, -- Need R + smtc2-LP-r16 SSB-MTC2-LP-r16 OPTIONAL, -- Need R + interFreqWhiteCellList-r16 InterFreqWhiteCellList-r16 OPTIONAL, -- Cond SharedSpectrum2 + ssb-PositionQCL-Common-r16 SSB-PositionQCL-Relation-r16 OPTIONAL, -- Cond SharedSpectrum + interFreqCAG-CellList-r16 SEQUENCE (SIZE (1..maxPLMN)) OF InterFreqCAG-CellList-r16 OPTIONAL -- Need R +} + +InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo + +InterFreqNeighCellList-v1610 ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo-v1610 + +InterFreqNeighCellInfo ::= SEQUENCE { + physCellId PhysCellId, + q-OffsetCell Q-OffsetRange, + q-RxLevMinOffsetCell INTEGER (1..8) OPTIONAL, -- Need R + q-RxLevMinOffsetCellSUL INTEGER (1..8) OPTIONAL, -- Need R + + ... +} + +InterFreqNeighCellInfo-v1610 ::= SEQUENCE { + ssb-PositionQCL-r16 SSB-PositionQCL-Relation-r16 OPTIONAL -- Cond SharedSpectrum2 +} + +InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PCI-Range + +InterFreqWhiteCellList-r16 ::= SEQUENCE (SIZE (1..maxCellWhite)) OF PCI-Range + +InterFreqCAG-CellList-r16 ::= SEQUENCE { + plmn-IdentityIndex-r16 INTEGER (1..maxPLMN), + cag-CellList-r16 SEQUENCE (SIZE (1..maxCAG-Cell-r16)) OF PCI-Range +} + +-- TAG-SIB4-STOP +-- TAG-SIB5-START + +SIB5 ::= SEQUENCE { + carrierFreqListEUTRA CarrierFreqListEUTRA OPTIONAL, -- Need R + t-ReselectionEUTRA T-Reselection, + t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need S + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + [[ + carrierFreqListEUTRA-v1610 CarrierFreqListEUTRA-v1610 OPTIONAL -- Need R + ]] +} + +CarrierFreqListEUTRA ::= SEQUENCE (SIZE (1..maxEUTRA-Carrier)) OF CarrierFreqEUTRA + +CarrierFreqListEUTRA-v1610 ::= SEQUENCE (SIZE (1..maxEUTRA-Carrier)) OF CarrierFreqEUTRA-v1610 + +CarrierFreqEUTRA ::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + eutra-multiBandInfoList EUTRA-MultiBandInfoList OPTIONAL, -- Need R + eutra-FreqNeighCellList EUTRA-FreqNeighCellList OPTIONAL, -- Need R + eutra-BlackCellList EUTRA-FreqBlackCellList OPTIONAL, -- Need R + allowedMeasBandwidth EUTRA-AllowedMeasBandwidth, + presenceAntennaPort1 EUTRA-PresenceAntennaPort1, + cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need R + cellReselectionSubPriority CellReselectionSubPriority OPTIONAL, -- Need R + threshX-High ReselectionThreshold, + threshX-Low ReselectionThreshold, + q-RxLevMin INTEGER (-70..-22), + q-QualMin INTEGER (-34..-3), + p-MaxEUTRA INTEGER (-30..33), + threshX-Q SEQUENCE { + threshX-HighQ ReselectionThresholdQ, + threshX-LowQ ReselectionThresholdQ + } OPTIONAL -- Cond RSRQ +} + +CarrierFreqEUTRA-v1610 ::= SEQUENCE { + highSpeedEUTRACarrier-r16 ENUMERATED {true} OPTIONAL -- Need R +} + +EUTRA-FreqBlackCellList ::= SEQUENCE (SIZE (1..maxEUTRA-CellBlack)) OF EUTRA-PhysCellIdRange + +EUTRA-FreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellEUTRA)) OF EUTRA-FreqNeighCellInfo + +EUTRA-FreqNeighCellInfo ::= SEQUENCE { + physCellId EUTRA-PhysCellId, + dummy EUTRA-Q-OffsetRange, + q-RxLevMinOffsetCell INTEGER (1..8) OPTIONAL, -- Need R + q-QualMinOffsetCell INTEGER (1..8) OPTIONAL -- Need R +} + +-- TAG-SIB5-STOP +-- TAG-SIB6-START + +SIB6 ::= SEQUENCE { + messageIdentifier BIT STRING (SIZE (16)), + serialNumber BIT STRING (SIZE (16)), + warningType OCTET STRING (SIZE (2)), + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIB6-STOP +-- TAG-SIB7-START + +SIB7 ::= SEQUENCE { + messageIdentifier BIT STRING (SIZE (16)), + serialNumber BIT STRING (SIZE (16)), + warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment}, + warningMessageSegmentNumber INTEGER (0..63), + warningMessageSegment OCTET STRING, + dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1 + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIB7-STOP +-- TAG-SIB8-START + +SIB8 ::= SEQUENCE { + messageIdentifier BIT STRING (SIZE (16)), + serialNumber BIT STRING (SIZE (16)), + warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment}, + warningMessageSegmentNumber INTEGER (0..63), + warningMessageSegment OCTET STRING, + dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1 + warningAreaCoordinatesSegment OCTET STRING OPTIONAL, -- Need R + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIB8-STOP +-- TAG-SIB9-START + +SIB9 ::= SEQUENCE { + timeInfo SEQUENCE { + timeInfoUTC INTEGER (0..549755813887), + dayLightSavingTime BIT STRING (SIZE (2)) OPTIONAL, -- Need R + leapSeconds INTEGER (-127..128) OPTIONAL, -- Need R + localTimeOffset INTEGER (-63..64) OPTIONAL -- Need R + } OPTIONAL, -- Need R + lateNonCriticalExtension OCTET STRING OPTIONAL, + ..., + [[ + referenceTimeInfo-r16 ReferenceTimeInfo-r16 OPTIONAL -- Need R + ]] +} + +-- TAG-SIB9-STOP +-- TAG-SIB10-START + +SIB10-r16 ::= SEQUENCE { + hrnn-List-r16 HRNN-List-r16 OPTIONAL, -- Need R + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +HRNN-List-r16 ::= SEQUENCE (SIZE (1..maxNPN-r16)) OF HRNN-r16 + +HRNN-r16 ::= SEQUENCE { + hrnn-r16 OCTET STRING (SIZE(1.. maxHRNN-Len-r16)) OPTIONAL -- Need R +} + +-- TAG-SIB10-STOP +-- TAG-SIB11-START + +SIB11-r16 ::= SEQUENCE { + measIdleConfigSIB-r16 MeasIdleConfigSIB-r16 OPTIONAL, -- Need S + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIB11-STOP +-- TAG-SIB12-START + +SIB12-r16 ::= SEQUENCE { + segmentNumber-r16 INTEGER (0..63), + segmentType-r16 ENUMERATED {notLastSegment, lastSegment}, + segmentContainer-r16 OCTET STRING +} + +SIB12-IEs-r16 ::= SEQUENCE { + sl-ConfigCommonNR-r16 SL-ConfigCommonNR-r16, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +SL-ConfigCommonNR-r16 ::= SEQUENCE { + sl-FreqInfoList-r16 SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF SL-FreqConfigCommon-r16 OPTIONAL, -- Need R + sl-UE-SelectedConfig-r16 SL-UE-SelectedConfig-r16 OPTIONAL, -- Need R + sl-NR-AnchorCarrierFreqList-r16 SL-NR-AnchorCarrierFreqList-r16 OPTIONAL, -- Need R + sl-EUTRA-AnchorCarrierFreqList-r16 SL-EUTRA-AnchorCarrierFreqList-r16 OPTIONAL, -- Need R + sl-RadioBearerConfigList-r16 SEQUENCE (SIZE (1..maxNrofSLRB-r16)) OF SL-RadioBearerConfig-r16 OPTIONAL, -- Need R + sl-RLC-BearerConfigList-r16 SEQUENCE (SIZE (1..maxSL-LCID-r16)) OF SL-RLC-BearerConfig-r16 OPTIONAL, -- Need R + sl-MeasConfigCommon-r16 SL-MeasConfigCommon-r16 OPTIONAL, -- Need R + sl-CSI-Acquisition-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + sl-OffsetDFN-r16 INTEGER (1..1000) OPTIONAL, -- Need R + t400-r16 ENUMERATED {ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, ms2000} OPTIONAL, -- Need R + sl-MaxNumConsecutiveDTX-r16 ENUMERATED {n1, n2, n3, n4, n6, n8, n16, n32} OPTIONAL, -- Need R + sl-SSB-PriorityNR-r16 INTEGER (1..8) OPTIONAL -- Need R +} + +SL-NR-AnchorCarrierFreqList-r16 ::= SEQUENCE (SIZE (1..maxFreqSL-NR-r16)) OF ARFCN-ValueNR + +SL-EUTRA-AnchorCarrierFreqList-r16 ::= SEQUENCE (SIZE (1..maxFreqSL-EUTRA-r16)) OF ARFCN-ValueEUTRA + +-- TAG-SIB12-STOP +-- TAG-SIB13-START + +SIB13-r16 ::= SEQUENCE { + sl-V2X-ConfigCommon-r16 OCTET STRING, + sl-Bandwidth-r16 OCTET STRING, + tdd-Config-r16 OCTET STRING, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIB13-STOP +-- TAG-SIB14-START + +SIB14-r16 ::= SEQUENCE { + sl-V2X-ConfigCommonExt-r16 OCTET STRING, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIB14-STOP +-- TAG-POSSYSTEMINFORMATION-R16-IES-START + +PosSystemInformation-r16-IEs ::= SEQUENCE { + posSIB-TypeAndInfo-r16 SEQUENCE (SIZE (1..maxSIB)) OF CHOICE { + posSib1-1-r16 SIBpos-r16, + posSib1-2-r16 SIBpos-r16, + posSib1-3-r16 SIBpos-r16, + posSib1-4-r16 SIBpos-r16, + posSib1-5-r16 SIBpos-r16, + posSib1-6-r16 SIBpos-r16, + posSib1-7-r16 SIBpos-r16, + posSib1-8-r16 SIBpos-r16, + posSib2-1-r16 SIBpos-r16, + posSib2-2-r16 SIBpos-r16, + posSib2-3-r16 SIBpos-r16, + posSib2-4-r16 SIBpos-r16, + posSib2-5-r16 SIBpos-r16, + posSib2-6-r16 SIBpos-r16, + posSib2-7-r16 SIBpos-r16, + posSib2-8-r16 SIBpos-r16, + posSib2-9-r16 SIBpos-r16, + posSib2-10-r16 SIBpos-r16, + posSib2-11-r16 SIBpos-r16, + posSib2-12-r16 SIBpos-r16, + posSib2-13-r16 SIBpos-r16, + posSib2-14-r16 SIBpos-r16, + posSib2-15-r16 SIBpos-r16, + posSib2-16-r16 SIBpos-r16, + posSib2-17-r16 SIBpos-r16, + posSib2-18-r16 SIBpos-r16, + posSib2-19-r16 SIBpos-r16, + posSib2-20-r16 SIBpos-r16, + posSib2-21-r16 SIBpos-r16, + posSib2-22-r16 SIBpos-r16, + posSib2-23-r16 SIBpos-r16, + posSib3-1-r16 SIBpos-r16, + posSib4-1-r16 SIBpos-r16, + posSib5-1-r16 SIBpos-r16, + posSib6-1-r16 SIBpos-r16, + posSib6-2-r16 SIBpos-r16, + posSib6-3-r16 SIBpos-r16, + ... + }, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-POSSYSTEMINFORMATION-R16-IES-STOP +-- TAG-POSSI-SCHEDULINGINFO-START + +PosSI-SchedulingInfo-r16 ::= SEQUENCE { + posSchedulingInfoList-r16 SEQUENCE (SIZE (1..maxSI-Message)) OF PosSchedulingInfo-r16, + posSI-RequestConfig-r16 SI-RequestConfig OPTIONAL, -- Cond MSG-1 + posSI-RequestConfigSUL-r16 SI-RequestConfig OPTIONAL, -- Cond SUL-MSG-1 + ... +} + +PosSchedulingInfo-r16 ::= SEQUENCE { + offsetToSI-Used-r16 ENUMERATED {true} OPTIONAL, -- Need R + posSI-Periodicity-r16 ENUMERATED {rf8, rf16, rf32, rf64, rf128, rf256, rf512}, + posSI-BroadcastStatus-r16 ENUMERATED {broadcasting, notBroadcasting}, + posSIB-MappingInfo-r16 PosSIB-MappingInfo-r16, + ... +} + +PosSIB-MappingInfo-r16 ::= SEQUENCE (SIZE (1..maxSIB)) OF PosSIB-Type-r16 + +PosSIB-Type-r16 ::= SEQUENCE { + encrypted-r16 ENUMERATED { true } OPTIONAL, -- Need R + gnss-id-r16 GNSS-ID-r16 OPTIONAL, -- Need R + sbas-id-r16 SBAS-ID-r16 OPTIONAL, -- Need R + posSibType-r16 ENUMERATED { posSibType1-1, posSibType1-2, posSibType1-3, posSibType1-4, posSibType1-5, posSibType1-6, + posSibType1-7, posSibType1-8, posSibType2-1, posSibType2-2, posSibType2-3, posSibType2-4, + posSibType2-5, posSibType2-6, posSibType2-7, posSibType2-8, posSibType2-9, posSibType2-10, + posSibType2-11, posSibType2-12, posSibType2-13, posSibType2-14, posSibType2-15, + posSibType2-16, posSibType2-17, posSibType2-18, posSibType2-19, posSibType2-20, + posSibType2-21, posSibType2-22, posSibType2-23, posSibType3-1, posSibType4-1, + posSibType5-1,posSibType6-1, posSibType6-2, posSibType6-3,... }, + areaScope-r16 ENUMERATED {true} OPTIONAL -- Need S +} + +GNSS-ID-r16 ::= SEQUENCE { + gnss-id-r16 ENUMERATED{gps, sbas, qzss, galileo, glonass, bds, ...}, + ... +} + +SBAS-ID-r16 ::= SEQUENCE { + sbas-id-r16 ENUMERATED { waas, egnos, msas, gagan, ...}, + ... +} + +-- TAG-POSSI-SCHEDULINGINFO-STOP +-- TAG-SIPOS-START + +SIBpos-r16 ::= SEQUENCE { + assistanceDataSIB-Element-r16 OCTET STRING, + lateNonCriticalExtension OCTET STRING OPTIONAL, + ... +} + +-- TAG-SIPOS-STOP +-- TAG-ADDITIONALSPECTRUMEMISSION-START + +AdditionalSpectrumEmission ::= INTEGER (0..7) + +-- TAG-ADDITIONALSPECTRUMEMISSION-STOP +-- TAG-ALPHA-START + +Alpha ::= ENUMERATED {alpha0, alpha04, alpha05, alpha06, alpha07, alpha08, alpha09, alpha1} + +-- TAG-ALPHA-STOP +-- TAG-AMF-IDENTIFIER-START + +AMF-Identifier ::= BIT STRING (SIZE (24)) + +-- TAG-AMF-IDENTIFIER-STOP +-- TAG-ARFCN-VALUEEUTRA-START + +ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN) + +-- TAG-ARFCN-VALUEEUTRA-STOP +-- TAG-ARFCN-VALUENR-START + +ARFCN-ValueNR ::= INTEGER (0..maxNARFCN) + +-- TAG-ARFCN-VALUENR-STOP +-- TAG-ARFCN-ValueUTRA-FDD-START + +ARFCN-ValueUTRA-FDD-r16 ::= INTEGER (0..16383) + +-- TAG-ARFCN-ValueUTRA-FDD-STOP +-- TAG-AVAILABILITYCOMBINATIONSPERCELL-START + +AvailabilityCombinationsPerCell-r16 ::= SEQUENCE { + availabilityCombinationsPerCellIndex-r16 AvailabilityCombinationsPerCellIndex-r16, + iab-DU-CellIdentity-r16 CellIdentity, + positionInDCI-AI-r16 INTEGER(0..maxAI-DCI-PayloadSize-r16-1) OPTIONAL, -- Need M + availabilityCombinations-r16 SEQUENCE (SIZE (1..maxNrofAvailabilityCombinationsPerSet-r16)) OF AvailabilityCombination-r16, + ... +} + +AvailabilityCombinationsPerCellIndex-r16 ::= INTEGER(0..maxNrofDUCells-r16) + +AvailabilityCombination-r16 ::= SEQUENCE { + availabilityCombinationId-r16 AvailabilityCombinationId-r16, + resourceAvailability-r16 SEQUENCE (SIZE (1..maxNrofResourceAvailabilityPerCombination-r16)) OF INTEGER (0..7) +} + +AvailabilityCombinationId-r16 ::= INTEGER (0..maxNrofAvailabilityCombinationsPerSet-r16-1) + +-- TAG-AVAILABILITYCOMBINATIONSPERCELL-STOP +-- TAG-AVAILABILITYINDICATOR-START + +AvailabilityIndicator-r16 ::= SEQUENCE { + ai-RNTI-r16 AI-RNTI-r16, + dci-PayloadSizeAI-r16 INTEGER (1..maxAI-DCI-PayloadSize-r16), + availableCombToAddModList-r16 SEQUENCE (SIZE(1..maxNrofDUCells-r16)) OF AvailabilityCombinationsPerCell-r16 OPTIONAL, -- Need N + availableCombToReleaseList-r16 SEQUENCE (SIZE(1..maxNrofDUCells-r16)) OF AvailabilityCombinationsPerCellIndex-r16 OPTIONAL, -- Need N + ... +} + +AI-RNTI-r16 ::= RNTI-Value + +-- TAG-AVAILABILITYINDICATOR-STOP +-- TAG-BAPROUTINGID-START + +BAP-Routing-ID-r16::= SEQUENCE{ + bap-Address-r16 BIT STRING (SIZE (10)), + bap-PathId-r16 BIT STRING (SIZE (10)) +} + +-- TAG-BAPROUTINGID-STOP +-- TAG-BEAMFAILURERECOVERYCONFIG-START + +BeamFailureRecoveryConfig ::= SEQUENCE { + rootSequenceIndex-BFR INTEGER (0..137) OPTIONAL, -- Need M + rach-ConfigBFR RACH-ConfigGeneric OPTIONAL, -- Need M + rsrp-ThresholdSSB RSRP-Range OPTIONAL, -- Need M + candidateBeamRSList SEQUENCE (SIZE(1..maxNrofCandidateBeams)) OF PRACH-ResourceDedicatedBFR OPTIONAL, -- Need M + ssb-perRACH-Occasion ENUMERATED {oneEighth, oneFourth, oneHalf, one, two, + four, eight, sixteen} OPTIONAL, -- Need M + ra-ssb-OccasionMaskIndex INTEGER (0..15) OPTIONAL, -- Need M + recoverySearchSpaceId SearchSpaceId OPTIONAL, -- Need R + ra-Prioritization RA-Prioritization OPTIONAL, -- Need R + beamFailureRecoveryTimer ENUMERATED {ms10, ms20, ms40, ms60, ms80, ms100, ms150, ms200} OPTIONAL, -- Need M + ..., + [[ + msg1-SubcarrierSpacing SubcarrierSpacing OPTIONAL -- Need M + ]], + [[ + ra-PrioritizationTwoStep-r16 RA-Prioritization OPTIONAL, -- Need R + candidateBeamRSListExt-v1610 SetupRelease{ CandidateBeamRSListExt-r16 } OPTIONAL -- Need M + ]] +} + +PRACH-ResourceDedicatedBFR ::= CHOICE { + ssb BFR-SSB-Resource, + csi-RS BFR-CSIRS-Resource +} + +BFR-SSB-Resource ::= SEQUENCE { + ssb SSB-Index, + ra-PreambleIndex INTEGER (0..63), + ... +} + +BFR-CSIRS-Resource ::= SEQUENCE { + csi-RS NZP-CSI-RS-ResourceId, + ra-OccasionList SEQUENCE (SIZE(1..maxRA-OccasionsPerCSIRS)) OF INTEGER (0..maxRA-Occasions-1) OPTIONAL, -- Need R + ra-PreambleIndex INTEGER (0..63) OPTIONAL, -- Need R + ... +} + +CandidateBeamRSListExt-r16::= SEQUENCE (SIZE(1.. maxNrofCandidateBeamsExt-r16)) OF PRACH-ResourceDedicatedBFR + +-- TAG-BEAMFAILURERECOVERYCONFIG-STOP +-- TAG-BEAMFAILURERECOVERYSCELLCONFIG-START + +BeamFailureRecoverySCellConfig-r16 ::= SEQUENCE { + rsrp-ThresholdBFR-r16 RSRP-Range OPTIONAL, -- Need M + candidateBeamRSSCellList-r16 SEQUENCE (SIZE(1..maxNrofCandidateBeams-r16)) OF CandidateBeamRS-r16 OPTIONAL, -- Need M + ... +} + +CandidateBeamRS-r16 ::= SEQUENCE { + candidateBeamConfig-r16 CHOICE { + ssb-r16 SSB-Index, + csi-RS-r16 NZP-CSI-RS-ResourceId + }, + servingCellId ServCellIndex OPTIONAL -- Need R +} + +-- TAG-BEAMFAILURERECOVERYSCELLCONFIG-STOP +-- TAG-BETAOFFSETS-START + +BetaOffsets ::= SEQUENCE { + betaOffsetACK-Index1 INTEGER(0..31) OPTIONAL, -- Need S + betaOffsetACK-Index2 INTEGER(0..31) OPTIONAL, -- Need S + betaOffsetACK-Index3 INTEGER(0..31) OPTIONAL, -- Need S + betaOffsetCSI-Part1-Index1 INTEGER(0..31) OPTIONAL, -- Need S + betaOffsetCSI-Part1-Index2 INTEGER(0..31) OPTIONAL, -- Need S + betaOffsetCSI-Part2-Index1 INTEGER(0..31) OPTIONAL, -- Need S + betaOffsetCSI-Part2-Index2 INTEGER(0..31) OPTIONAL -- Need S +} + +-- TAG-BETAOFFSETS-STOP +-- TAG-BH-RLCCHANNELCONFIG-START + +BH-RLC-ChannelConfig-r16::= SEQUENCE { + bh-LogicalChannelIdentity-r16 BH-LogicalChannelIdentity-r16 OPTIONAL, -- Cond LCH-SetupOnly + bh-RLC-ChannelID-r16 BH-RLC-ChannelID-r16, + reestablishRLC-r16 ENUMERATED {true} OPTIONAL, -- Need N + rlc-Config-r16 RLC-Config OPTIONAL, -- Cond LCH-Setup + mac-LogicalChannelConfig-r16 LogicalChannelConfig OPTIONAL, -- Cond LCH-Setup + ... +} + +-- TAG-BH-RLCCHANNELCONFIG-STOP +-- TAG-BH-LOGICALCHANNELIDENTITY-START + +BH-LogicalChannelIdentity-r16 ::= CHOICE { + bh-LogicalChannelIdentity-r16 LogicalChannelIdentity, + bh-LogicalChannelIdentityExt-r16 BH-LogicalChannelIdentity-Ext-r16 +} + +-- TAG-BH-LOGICALCHANNELIDENTITY-STOP +-- TAG-BH-LOGICALCHANNELIDENTITY-Ext-START + +BH-LogicalChannelIdentity-Ext-r16 ::= INTEGER (33.. maxLC-ID-Iab-r16) + +-- TAG-BH-LOGICALCHANNELIDENTITY-Ext-STOP +-- TAG-BHRLCCHANNELID-START + +BH-RLC-ChannelID-r16 ::= BIT STRING (SIZE (16)) + +-- TAG-BHRLCCHANNELID-STOP +-- TAG-BSR-CONFIG-START + +BSR-Config ::= SEQUENCE { + periodicBSR-Timer ENUMERATED { sf1, sf5, sf10, sf16, sf20, sf32, sf40, sf64, + sf80, sf128, sf160, sf320, sf640, sf1280, sf2560, infinity }, + retxBSR-Timer ENUMERATED { sf10, sf20, sf40, sf80, sf160, sf320, sf640, sf1280, sf2560, + sf5120, sf10240, spare5, spare4, spare3, spare2, spare1}, + logicalChannelSR-DelayTimer ENUMERATED { sf20, sf40, sf64, sf128, sf512, sf1024, sf2560, spare1} OPTIONAL, -- Need R + ... +} + +-- TAG-BSR-CONFIG-STOP +-- TAG-BWP-START + +BWP ::= SEQUENCE { + locationAndBandwidth INTEGER (0..37949), + subcarrierSpacing SubcarrierSpacing, + cyclicPrefix ENUMERATED { extended } OPTIONAL -- Need R +} + + +-- TAG-BWP-STOP +-- TAG-BWP-DOWNLINK-START + +BWP-Downlink ::= SEQUENCE { + bwp-Id BWP-Id, + bwp-Common BWP-DownlinkCommon OPTIONAL, -- Cond SetupOtherBWP + bwp-Dedicated BWP-DownlinkDedicated OPTIONAL, -- Cond SetupOtherBWP + ... +} + +-- TAG-BWP-DOWNLINK-STOP +-- TAG-BWP-DOWNLINKCOMMON-START + +BWP-DownlinkCommon ::= SEQUENCE { + genericParameters BWP, + pdcch-ConfigCommon SetupRelease { PDCCH-ConfigCommon } OPTIONAL, -- Need M + pdsch-ConfigCommon SetupRelease { PDSCH-ConfigCommon } OPTIONAL, -- Need M + ... +} + +-- TAG-BWP-DOWNLINKCOMMON-STOP +-- TAG-BWP-DOWNLINKDEDICATED-START + +BWP-DownlinkDedicated ::= SEQUENCE { + pdcch-Config SetupRelease { PDCCH-Config } OPTIONAL, -- Need M + pdsch-Config SetupRelease { PDSCH-Config } OPTIONAL, -- Need M + sps-Config SetupRelease { SPS-Config } OPTIONAL, -- Need M + radioLinkMonitoringConfig SetupRelease { RadioLinkMonitoringConfig } OPTIONAL, -- Need M + ..., + [[ + sps-ConfigToAddModList-r16 SPS-ConfigToAddModList-r16 OPTIONAL, -- Need N + sps-ConfigToReleaseList-r16 SPS-ConfigToReleaseList-r16 OPTIONAL, -- Need N + sps-ConfigDeactivationStateList-r16 SPS-ConfigDeactivationStateList-r16 OPTIONAL, -- Need R + beamFailureRecoverySCellConfig-r16 SetupRelease {BeamFailureRecoverySCellConfig-r16} OPTIONAL, -- Cond SCellOnly + sl-PDCCH-Config-r16 SetupRelease { PDCCH-Config } OPTIONAL, -- Need M + sl-V2X-PDCCH-Config-r16 SetupRelease { PDCCH-Config } OPTIONAL -- Need M + ]] +} + +SPS-ConfigToAddModList-r16 ::= SEQUENCE (SIZE (1..maxNrofSPS-Config-r16)) OF SPS-Config + +SPS-ConfigToReleaseList-r16 ::= SEQUENCE (SIZE (1..maxNrofSPS-Config-r16)) OF SPS-ConfigIndex-r16 + +SPS-ConfigDeactivationState-r16 ::= SEQUENCE (SIZE (1..maxNrofSPS-Config-r16)) OF SPS-ConfigIndex-r16 + +SPS-ConfigDeactivationStateList-r16 ::= SEQUENCE (SIZE (1..maxNrofSPS-DeactivationState)) OF SPS-ConfigDeactivationState-r16 + +-- TAG-BWP-DOWNLINKDEDICATED-STOP +-- TAG-BWP-ID-START + +BWP-Id ::= INTEGER (0..maxNrofBWPs) + +-- TAG-BWP-ID-STOP +-- TAG-BWP-UPLINK-START + +BWP-Uplink ::= SEQUENCE { + bwp-Id BWP-Id, + bwp-Common BWP-UplinkCommon OPTIONAL, -- Cond SetupOtherBWP + bwp-Dedicated BWP-UplinkDedicated OPTIONAL, -- Cond SetupOtherBWP + ... +} + +-- TAG-BWP-UPLINK-STOP +-- TAG-BWP-UPLINKCOMMON-START + +BWP-UplinkCommon ::= SEQUENCE { + genericParameters BWP, + rach-ConfigCommon SetupRelease { RACH-ConfigCommon } OPTIONAL, -- Need M + pusch-ConfigCommon SetupRelease { PUSCH-ConfigCommon } OPTIONAL, -- Need M + pucch-ConfigCommon SetupRelease { PUCCH-ConfigCommon } OPTIONAL, -- Need M + ..., + [[ + rach-ConfigCommonIAB-r16 SetupRelease { RACH-ConfigCommon } OPTIONAL, -- Need M + useInterlacePUCCH-PUSCH-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + msgA-ConfigCommon-r16 SetupRelease { MsgA-ConfigCommon-r16 } OPTIONAL -- Cond SpCellOnly2 + ]] +} + +-- TAG-BWP-UPLINKCOMMON-STOP +-- TAG-BWP-UPLINKDEDICATED-START + +BWP-UplinkDedicated ::= SEQUENCE { + pucch-Config SetupRelease { PUCCH-Config } OPTIONAL, -- Need M + pusch-Config SetupRelease { PUSCH-Config } OPTIONAL, -- Need M + configuredGrantConfig SetupRelease { ConfiguredGrantConfig } OPTIONAL, -- Need M + srs-Config SetupRelease { SRS-Config } OPTIONAL, -- Need M + beamFailureRecoveryConfig SetupRelease { BeamFailureRecoveryConfig } OPTIONAL, -- Cond SpCellOnly + ..., + [[ + sl-PUCCH-Config-r16 SetupRelease { PUCCH-Config } OPTIONAL, -- Need M + cp-ExtensionC2-r16 INTEGER (1..28) OPTIONAL, -- Need R + cp-ExtensionC3-r16 INTEGER (1..28) OPTIONAL, -- Need R + useInterlacePUCCH-PUSCH-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + pucch-ConfigurationList-r16 SetupRelease { PUCCH-ConfigurationList-r16 } OPTIONAL, -- Need M + lbt-FailureRecoveryConfig-r16 SetupRelease { LBT-FailureRecoveryConfig-r16 } OPTIONAL, -- Need M + configuredGrantConfigToAddModList-r16 ConfiguredGrantConfigToAddModList-r16 OPTIONAL, -- Need N + configuredGrantConfigToReleaseList-r16 ConfiguredGrantConfigToReleaseList-r16 OPTIONAL, -- Need N + configuredGrantConfigType2DeactivationStateList-r16 ConfiguredGrantConfigType2DeactivationStateList-r16 OPTIONAL -- Need R + ]] + +} + +ConfiguredGrantConfigToAddModList-r16 ::= SEQUENCE (SIZE (1..maxNrofConfiguredGrantConfig-r16)) OF ConfiguredGrantConfig + +ConfiguredGrantConfigToReleaseList-r16 ::= SEQUENCE (SIZE (1..maxNrofConfiguredGrantConfig-r16)) OF ConfiguredGrantConfigIndex-r16 + +ConfiguredGrantConfigType2DeactivationState-r16 ::= SEQUENCE (SIZE (1..maxNrofConfiguredGrantConfig-r16)) OF ConfiguredGrantConfigIndex-r16 + +ConfiguredGrantConfigType2DeactivationStateList-r16 ::= + SEQUENCE (SIZE (1..maxNrofCG-Type2DeactivationState)) OF ConfiguredGrantConfigType2DeactivationState-r16 + +-- TAG-BWP-UPLINKDEDICATED-STOP +-- TAG-CELLACCESSRELATEDINFO-START + +CellAccessRelatedInfo ::= SEQUENCE { + plmn-IdentityList PLMN-IdentityInfoList, + cellReservedForOtherUse ENUMERATED {true} OPTIONAL, -- Need R + ..., + [[ + cellReservedForFutureUse-r16 ENUMERATED {true} OPTIONAL, -- Need R + npn-IdentityInfoList-r16 NPN-IdentityInfoList-r16 OPTIONAL -- Need R + ]] +} + +-- TAG-CELLACCESSRELATEDINFO-STOP +-- TAG-CELLACCESSRELATEDINFOEUTRA-5GC-START + +CellAccessRelatedInfo-EUTRA-5GC ::= SEQUENCE { + plmn-IdentityList-eutra-5gc PLMN-IdentityList-EUTRA-5GC, + trackingAreaCode-eutra-5gc TrackingAreaCode, + ranac-5gc RAN-AreaCode OPTIONAL, + cellIdentity-eutra-5gc CellIdentity-EUTRA-5GC +} + +PLMN-IdentityList-EUTRA-5GC::= SEQUENCE (SIZE (1..maxPLMN)) OF PLMN-Identity-EUTRA-5GC + +PLMN-Identity-EUTRA-5GC ::= CHOICE { + plmn-Identity-EUTRA-5GC PLMN-Identity, + plmn-index INTEGER (1..maxPLMN) +} + +CellIdentity-EUTRA-5GC ::= CHOICE { + cellIdentity-EUTRA BIT STRING (SIZE (28)), + cellId-index INTEGER (1..maxPLMN) +} + +-- TAG-CELLACCESSRELATEDINFOEUTRA-5GC-STOP +-- TAG-CELLACCESSRELATEDINFOEUTRA-EPC-START + +CellAccessRelatedInfo-EUTRA-EPC ::= SEQUENCE { + plmn-IdentityList-eutra-epc PLMN-IdentityList-EUTRA-EPC, + trackingAreaCode-eutra-epc BIT STRING (SIZE (16)), + cellIdentity-eutra-epc BIT STRING (SIZE (28)) +} + +PLMN-IdentityList-EUTRA-EPC::= SEQUENCE (SIZE (1..maxPLMN)) OF PLMN-Identity + +-- TAG-CELLACCESSRELATEDINFOEUTRA-EPC-STOP +-- TAG-CELLGROUPCONFIG-START + +-- Configuration of one Cell-Group: +CellGroupConfig ::= SEQUENCE { + cellGroupId CellGroupId, + rlc-BearerToAddModList SEQUENCE (SIZE(1..maxLC-ID)) OF RLC-BearerConfig OPTIONAL, -- Need N + rlc-BearerToReleaseList SEQUENCE (SIZE(1..maxLC-ID)) OF LogicalChannelIdentity OPTIONAL, -- Need N + mac-CellGroupConfig MAC-CellGroupConfig OPTIONAL, -- Need M + physicalCellGroupConfig PhysicalCellGroupConfig OPTIONAL, -- Need M + spCellConfig SpCellConfig OPTIONAL, -- Need M + sCellToAddModList SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellConfig OPTIONAL, -- Need N + sCellToReleaseList SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellIndex OPTIONAL, -- Need N + ..., + [[ + reportUplinkTxDirectCurrent ENUMERATED {true} OPTIONAL -- Cond BWP-Reconfig + ]], + [[ + bap-Address-r16 BIT STRING (SIZE (10)) OPTIONAL, -- Need M + bh-RLC-ChannelToAddModList-r16 SEQUENCE (SIZE(1..maxBH-RLC-ChannelID-r16)) OF BH-RLC-ChannelConfig-r16 OPTIONAL, -- Need N + bh-RLC-ChannelToReleaseList-r16 SEQUENCE (SIZE(1..maxBH-RLC-ChannelID-r16)) OF BH-RLC-ChannelID-r16 OPTIONAL, -- Need N + f1c-TransferPath-r16 ENUMERATED {lte, nr, both} OPTIONAL, -- Need M + simultaneousTCI-UpdateList1-r16 SEQUENCE (SIZE (1..maxNrofServingCellsTCI-r16)) OF ServCellIndex OPTIONAL, -- Need R + simultaneousTCI-UpdateList2-r16 SEQUENCE (SIZE (1..maxNrofServingCellsTCI-r16)) OF ServCellIndex OPTIONAL, -- Need R + simultaneousSpatial-UpdatedList1-r16 SEQUENCE (SIZE (1..maxNrofServingCellsTCI-r16)) OF ServCellIndex OPTIONAL, -- Need R + simultaneousSpatial-UpdatedList2-r16 SEQUENCE (SIZE (1..maxNrofServingCellsTCI-r16)) OF ServCellIndex OPTIONAL, -- Need R + uplinkTxSwitchingOption-r16 ENUMERATED {switchedUL, dualUL} OPTIONAL -- Need R + ]] +} + +-- Serving cell specific MAC and PHY parameters for a SpCell: +SpCellConfig ::= SEQUENCE { + servCellIndex ServCellIndex OPTIONAL, -- Cond SCG + reconfigurationWithSync ReconfigurationWithSync OPTIONAL, -- Cond ReconfWithSync + rlf-TimersAndConstants SetupRelease { RLF-TimersAndConstants } OPTIONAL, -- Need M + rlmInSyncOutOfSyncThreshold ENUMERATED {n1} OPTIONAL, -- Need S + spCellConfigDedicated ServingCellConfig OPTIONAL, -- Need M + ... +} + +ReconfigurationWithSync ::= SEQUENCE { + spCellConfigCommon ServingCellConfigCommon OPTIONAL, -- Need M + newUE-Identity RNTI-Value, + t304 ENUMERATED {ms50, ms100, ms150, ms200, ms500, ms1000, ms2000, ms10000}, + rach-ConfigDedicated CHOICE { + uplink RACH-ConfigDedicated, + supplementaryUplink RACH-ConfigDedicated + } OPTIONAL, -- Need N + ..., + [[ + smtc SSB-MTC OPTIONAL -- Need S + ]], + [[ + daps-UplinkPowerConfig-r16 DAPS-UplinkPowerConfig-r16 OPTIONAL -- Need N + ]] +} + +DAPS-UplinkPowerConfig-r16 ::= SEQUENCE { + p-DAPS-Source-r16 P-Max, + p-DAPS-Target-r16 P-Max, + uplinkPowerSharingDAPS-Mode-r16 ENUMERATED {semi-static-mode1, semi-static-mode2, dynamic } +} + +SCellConfig ::= SEQUENCE { + sCellIndex SCellIndex, + sCellConfigCommon ServingCellConfigCommon OPTIONAL, -- Cond SCellAdd + sCellConfigDedicated ServingCellConfig OPTIONAL, -- Cond SCellAddMod + ..., + [[ + smtc SSB-MTC OPTIONAL -- Need S + ]], + [[ + sCellState-r16 ENUMERATED {activated} OPTIONAL, -- Cond SCellAddSync + secondaryDRX-GroupConfig-r16 ENUMERATED {true} OPTIONAL -- Cond DRX-Config2 + ]]} + +-- TAG-CELLGROUPCONFIG-STOP +-- TAG-CELLGROUPID-START + +CellGroupId ::= INTEGER (0.. maxSecondaryCellGroups) + +-- TAG-CELLGROUPID-STOP +-- TAG-CELLIDENTITY-START + +CellIdentity ::= BIT STRING (SIZE (36)) + +-- TAG-CELLIDENTITY-STOP +-- TAG-CELLRESELECTIONPRIORITY-START + +CellReselectionPriority ::= INTEGER (0..7) + +-- TAG-CELLRESELECTIONPRIORITY-STOP +-- TAG-CELLRESELECTIONSUBPRIORITY-START + +CellReselectionSubPriority ::= ENUMERATED {oDot2, oDot4, oDot6, oDot8} + +-- TAG-CELLRESELECTIONSUBPRIORITY-STOP +-- TAG-CGI-INFOEUTRA-START + +CGI-InfoEUTRA ::= SEQUENCE { + cgi-info-EPC SEQUENCE { + cgi-info-EPC-legacy CellAccessRelatedInfo-EUTRA-EPC, + cgi-info-EPC-list SEQUENCE (SIZE (1..maxPLMN)) OF CellAccessRelatedInfo-EUTRA-EPC OPTIONAL + } OPTIONAL, + cgi-info-5GC SEQUENCE (SIZE (1..maxPLMN)) OF CellAccessRelatedInfo-EUTRA-5GC OPTIONAL, + freqBandIndicator FreqBandIndicatorEUTRA, + multiBandInfoList MultiBandInfoListEUTRA OPTIONAL, + freqBandIndicatorPriority ENUMERATED {true} OPTIONAL +} + +-- TAG-CGI-INFOEUTRA-STOP +-- TAG-CGI-INFOEUTRALOGGING-START + +CGI-InfoEUTRALogging ::= SEQUENCE { + plmn-Identity-eutra-5gc PLMN-Identity OPTIONAL, + trackingAreaCode-eutra-5gc TrackingAreaCode OPTIONAL, + cellIdentity-eutra-5gc BIT STRING (SIZE (28)) OPTIONAL, + plmn-Identity-eutra-epc PLMN-Identity OPTIONAL, + trackingAreaCode-eutra-epc BIT STRING (SIZE (16)) OPTIONAL, + cellIdentity-eutra-epc BIT STRING (SIZE (28)) OPTIONAL +} + +-- TAG-CGI-INFOEUTRALOGGING-STOP +-- TAG-CGI-INFO-NR-START + +CGI-InfoNR ::= SEQUENCE { + plmn-IdentityInfoList PLMN-IdentityInfoList OPTIONAL, + frequencyBandList MultiFrequencyBandListNR OPTIONAL, + noSIB1 SEQUENCE { + ssb-SubcarrierOffset INTEGER (0..15), + pdcch-ConfigSIB1 PDCCH-ConfigSIB1 + } OPTIONAL, + ..., + [[ + npn-IdentityInfoList-r16 NPN-IdentityInfoList-r16 OPTIONAL + ]] +} + +-- TAG-CGI-INFO-NR-STOP +-- TAG-CGI-INFO-LOGGING-START + +CGI-Info-Logging-r16 ::= SEQUENCE { + plmn-Identity-r16 PLMN-Identity, + cellIdentity-r16 CellIdentity, + trackingAreaCode-r16 TrackingAreaCode OPTIONAL +} + +-- TAG-CGI-INFO-LOGGING-STOP +-- TAG-CLI-RSSI-RANGE-START + +CLI-RSSI-Range-r16 ::= INTEGER(0..76) + +-- TAG-CLI-RSSI-RANGE-STOP +-- TAG-CODEBOOKCONFIG-START + +CodebookConfig ::= SEQUENCE { + codebookType CHOICE { + type1 SEQUENCE { + subType CHOICE { + typeI-SinglePanel SEQUENCE { + nrOfAntennaPorts CHOICE { + two SEQUENCE { + twoTX-CodebookSubsetRestriction BIT STRING (SIZE (6)) + }, + moreThanTwo SEQUENCE { + n1-n2 CHOICE { + two-one-TypeI-SinglePanel-Restriction BIT STRING (SIZE (8)), + two-two-TypeI-SinglePanel-Restriction BIT STRING (SIZE (64)), + four-one-TypeI-SinglePanel-Restriction BIT STRING (SIZE (16)), + three-two-TypeI-SinglePanel-Restriction BIT STRING (SIZE (96)), + six-one-TypeI-SinglePanel-Restriction BIT STRING (SIZE (24)), + four-two-TypeI-SinglePanel-Restriction BIT STRING (SIZE (128)), + eight-one-TypeI-SinglePanel-Restriction BIT STRING (SIZE (32)), + four-three-TypeI-SinglePanel-Restriction BIT STRING (SIZE (192)), + six-two-TypeI-SinglePanel-Restriction BIT STRING (SIZE (192)), + twelve-one-TypeI-SinglePanel-Restriction BIT STRING (SIZE (48)), + four-four-TypeI-SinglePanel-Restriction BIT STRING (SIZE (256)), + eight-two-TypeI-SinglePanel-Restriction BIT STRING (SIZE (256)), + sixteen-one-TypeI-SinglePanel-Restriction BIT STRING (SIZE (64)) + }, + typeI-SinglePanel-codebookSubsetRestriction-i2 BIT STRING (SIZE (16)) OPTIONAL -- Need R + } + }, + typeI-SinglePanel-ri-Restriction BIT STRING (SIZE (8)) + }, + typeI-MultiPanel SEQUENCE { + ng-n1-n2 CHOICE { + two-two-one-TypeI-MultiPanel-Restriction BIT STRING (SIZE (8)), + two-four-one-TypeI-MultiPanel-Restriction BIT STRING (SIZE (16)), + four-two-one-TypeI-MultiPanel-Restriction BIT STRING (SIZE (8)), + two-two-two-TypeI-MultiPanel-Restriction BIT STRING (SIZE (64)), + two-eight-one-TypeI-MultiPanel-Restriction BIT STRING (SIZE (32)), + four-four-one-TypeI-MultiPanel-Restriction BIT STRING (SIZE (16)), + two-four-two-TypeI-MultiPanel-Restriction BIT STRING (SIZE (128)), + four-two-two-TypeI-MultiPanel-Restriction BIT STRING (SIZE (64)) + }, + ri-Restriction BIT STRING (SIZE (4)) + } + }, + codebookMode INTEGER (1..2) + + }, + type2 SEQUENCE { + subType CHOICE { + typeII SEQUENCE { + n1-n2-codebookSubsetRestriction CHOICE { + two-one BIT STRING (SIZE (16)), + two-two BIT STRING (SIZE (43)), + four-one BIT STRING (SIZE (32)), + three-two BIT STRING (SIZE (59)), + six-one BIT STRING (SIZE (48)), + four-two BIT STRING (SIZE (75)), + eight-one BIT STRING (SIZE (64)), + four-three BIT STRING (SIZE (107)), + six-two BIT STRING (SIZE (107)), + twelve-one BIT STRING (SIZE (96)), + four-four BIT STRING (SIZE (139)), + eight-two BIT STRING (SIZE (139)), + sixteen-one BIT STRING (SIZE (128)) + }, + typeII-RI-Restriction BIT STRING (SIZE (2)) + }, + typeII-PortSelection SEQUENCE { + portSelectionSamplingSize ENUMERATED {n1, n2, n3, n4} OPTIONAL, -- Need R + typeII-PortSelectionRI-Restriction BIT STRING (SIZE (2)) + } + }, + phaseAlphabetSize ENUMERATED {n4, n8}, + subbandAmplitude BOOLEAN, + numberOfBeams ENUMERATED {two, three, four} + } + } +} + +CodebookConfig-r16 ::= SEQUENCE { + codebookType CHOICE { + type2 SEQUENCE { + subType CHOICE { + typeII-r16 SEQUENCE { + n1-n2-codebookSubsetRestriction-r16 CHOICE { + two-one BIT STRING (SIZE (16)), + two-two BIT STRING (SIZE (43)), + four-one BIT STRING (SIZE (32)), + three-two BIT STRING (SIZE (59)), + six-one BIT STRING (SIZE (48)), + four-two BIT STRING (SIZE (75)), + eight-one BIT STRING (SIZE (64)), + four-three BIT STRING (SIZE (107)), + six-two BIT STRING (SIZE (107)), + twelve-one BIT STRING (SIZE (96)), + four-four BIT STRING (SIZE (139)), + eight-two BIT STRING (SIZE (139)), + sixteen-one BIT STRING (SIZE (128)) + }, + typeII-RI-Restriction-r16 BIT STRING (SIZE(4)) + }, + typeII-PortSelection-r16 SEQUENCE { + portSelectionSamplingSize-r16 ENUMERATED {n1, n2, n3, n4}, + typeII-PortSelectionRI-Restriction-r16 BIT STRING (SIZE (4)) + } + }, + numberOfPMI-SubbandsPerCQI-Subband-r16 INTEGER (1..2), + paramCombination-r16 INTEGER (1..8) + } + } +} + +-- TAG-CODEBOOKCONFIG-STOP +-- TAG-COMMONLOCATIONINFO-START + +CommonLocationInfo-r16 ::= SEQUENCE { + gnss-TOD-msec-r16 OCTET STRING OPTIONAL, + locationTimestamp-r16 OCTET STRING OPTIONAL, + locationCoordinate-r16 OCTET STRING OPTIONAL, + locationError-r16 OCTET STRING OPTIONAL, + locationSource-r16 OCTET STRING OPTIONAL, + velocityEstimate-r16 OCTET STRING OPTIONAL +} + +-- TAG-COMMONLOCATIONINFO-STOP +-- TAG-CONDRECONFIGID-START + +CondReconfigId-r16 ::= INTEGER (1.. maxNrofCondCells-r16) + +-- TAG-CONDRECONFIGID-STOP +-- TAG-CONDRECONFIGTOADDMODLIST-START + +CondReconfigToAddModList-r16 ::= SEQUENCE (SIZE (1.. maxNrofCondCells-r16)) OF CondReconfigToAddMod-r16 + +CondReconfigToAddMod-r16 ::= SEQUENCE { + condReconfigId-r16 CondReconfigId-r16, + condExecutionCond-r16 SEQUENCE (SIZE (1..2)) OF MeasId OPTIONAL, -- Cond condReconfigAdd + condRRCReconfig-r16 OCTET STRING (CONTAINING RRCReconfiguration) OPTIONAL, -- Cond condReconfigAdd + ... +} + +-- TAG-CONDRECONFIGTOADDMODLIST-STOP +-- TAG-CONDITIONALRECONFIGURATION-START + +ConditionalReconfiguration-r16 ::= SEQUENCE { + attemptCondReconfig-r16 ENUMERATED {true} OPTIONAL, -- Cond PCell + condReconfigToRemoveList-r16 CondReconfigToRemoveList-r16 OPTIONAL, -- Need N + condReconfigToAddModList-r16 CondReconfigToAddModList-r16 OPTIONAL, -- Need N + ... +} + +CondReconfigToRemoveList-r16 ::= SEQUENCE (SIZE (1.. maxNrofCondCells-r16)) OF CondReconfigId-r16 + +-- TAG-CONDITIONALRECONFIGURATION-STOP +-- TAG-CONFIGUREDGRANTCONFIG-START + +ConfiguredGrantConfig ::= SEQUENCE { + frequencyHopping ENUMERATED {intraSlot, interSlot} OPTIONAL, -- Need S + cg-DMRS-Configuration DMRS-UplinkConfig, + mcs-Table ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + mcs-TableTransformPrecoder ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + uci-OnPUSCH SetupRelease { CG-UCI-OnPUSCH } OPTIONAL, -- Need M + resourceAllocation ENUMERATED { resourceAllocationType0, resourceAllocationType1, dynamicSwitch }, + rbg-Size ENUMERATED {config2} OPTIONAL, -- Need S + powerControlLoopToUse ENUMERATED {n0, n1}, + p0-PUSCH-Alpha P0-PUSCH-AlphaSetId, + transformPrecoder ENUMERATED {enabled, disabled} OPTIONAL, -- Need S + nrofHARQ-Processes INTEGER(1..16), + repK ENUMERATED {n1, n2, n4, n8}, + repK-RV ENUMERATED {s1-0231, s2-0303, s3-0000} OPTIONAL, -- Need R + periodicity ENUMERATED { + sym2, sym7, sym1x14, sym2x14, sym4x14, sym5x14, sym8x14, sym10x14, sym16x14, sym20x14, + sym32x14, sym40x14, sym64x14, sym80x14, sym128x14, sym160x14, sym256x14, sym320x14, sym512x14, + sym640x14, sym1024x14, sym1280x14, sym2560x14, sym5120x14, + sym6, sym1x12, sym2x12, sym4x12, sym5x12, sym8x12, sym10x12, sym16x12, sym20x12, sym32x12, + sym40x12, sym64x12, sym80x12, sym128x12, sym160x12, sym256x12, sym320x12, sym512x12, sym640x12, + sym1280x12, sym2560x12 + }, + configuredGrantTimer INTEGER (1..64) OPTIONAL, -- Need R + rrc-ConfiguredUplinkGrant SEQUENCE { + timeDomainOffset INTEGER (0..5119), + timeDomainAllocation INTEGER (0..15), + frequencyDomainAllocation BIT STRING (SIZE(18)), + antennaPort INTEGER (0..31), + dmrs-SeqInitialization INTEGER (0..1) OPTIONAL, -- Need R + precodingAndNumberOfLayers INTEGER (0..63), + srs-ResourceIndicator INTEGER (0..15) OPTIONAL, -- Need R + mcsAndTBS INTEGER (0..31), + frequencyHoppingOffset INTEGER (1.. maxNrofPhysicalResourceBlocks-1) OPTIONAL, -- Need R + pathlossReferenceIndex INTEGER (0..maxNrofPUSCH-PathlossReferenceRSs-1), + ..., + [[ + pusch-RepTypeIndicator-r16 ENUMERATED {pusch-RepTypeA,pusch-RepTypeB} OPTIONAL, -- Need M + frequencyHoppingPUSCH-RepTypeB-r16 ENUMERATED {interRepetition, interSlot} OPTIONAL, -- Cond RepTypeB + timeReferenceSFN-r16 ENUMERATED {sfn512} OPTIONAL -- Need S + ]] + } OPTIONAL, -- Need R + ..., + [[ + cg-RetransmissionTimer-r16 INTEGER (1..64) OPTIONAL, -- Need R + cg-minDFI-Delay-r16 ENUMERATED + {sym7, sym1x14, sym2x14, sym3x14, sym4x14, sym5x14, sym6x14, sym7x14, sym8x14, + sym9x14, sym10x14, sym11x14, sym12x14, sym13x14, sym14x14,sym15x14, sym16x14 + } OPTIONAL, -- Need R + cg-nrofPUSCH-InSlot-r16 INTEGER (1..7) OPTIONAL, -- Need R + cg-nrofSlots-r16 INTEGER (1..40) OPTIONAL, -- Need R + cg-StartingOffsets-r16 CG-StartingOffsets-r16 OPTIONAL, -- Need R + cg-UCI-Multiplexing ENUMERATED {enabled} OPTIONAL, -- Need R + cg-COT-SharingOffset-r16 INTEGER (1..39) OPTIONAL, -- Need R + betaOffsetCG-UCI-r16 INTEGER (0.. 31) OPTIONAL, -- Need R + cg-COT-SharingList-r16 SEQUENCE (SIZE (1..1709)) OF CG-COT-Sharing-r16 OPTIONAL, -- Need R + harq-ProcID-Offset-r16 INTEGER (0..15) OPTIONAL, -- Need M + harq-ProcID-Offset2-r16 INTEGER (0..15) OPTIONAL, -- Need M + configuredGrantConfigIndex-r16 ConfiguredGrantConfigIndex-r16 OPTIONAL, -- Cond CG-List + configuredGrantConfigIndexMAC-r16 ConfiguredGrantConfigIndexMAC-r16 OPTIONAL, -- Cond CG-List + periodicityExt-r16 INTEGER (1..5120) OPTIONAL, -- Need R + startingFromRV0-r16 ENUMERATED {on, off} OPTIONAL, -- Need R + phy-PriorityIndex-r16 ENUMERATED {p0, p1} OPTIONAL, -- Need R + autonomousTx-r16 ENUMERATED {enabled} OPTIONAL -- Cond LCH-BasedPrioritization + ]] + +} + +CG-UCI-OnPUSCH ::= CHOICE { + dynamic SEQUENCE (SIZE (1..4)) OF BetaOffsets, + semiStatic BetaOffsets +} + +CG-COT-Sharing-r16 ::= CHOICE { + noCOT-Sharing-r16 NULL, + cot-Sharing-r16 SEQUENCE { + duration-r16 INTEGER (1.. 39), + offset-r16 INTEGER (1.. 39), + channelAccessPriority-r16 INTEGER (1..4) + } +} + +CG-StartingOffsets-r16 ::= SEQUENCE { + cg-StartingFullBW-InsideCOT-r16 SEQUENCE (SIZE (1..7)) OF INTEGER (0..6) OPTIONAL, -- Need R + cg-StartingFullBW-OutsideCOT-r16 SEQUENCE (SIZE (1..7)) OF INTEGER (0..6) OPTIONAL, -- Need R + cg-StartingPartialBW-InsideCOT-r16 INTEGER (0..6) OPTIONAL, -- Need R + cg-StartingPartialBW-OutsideCOT-r16 INTEGER (0..6) OPTIONAL -- Need R +} + +-- TAG-CONFIGUREDGRANTCONFIG-STOP +-- TAG-CONFIGUREDGRANTCONFIGINDEX-START + +ConfiguredGrantConfigIndex-r16 ::= INTEGER (0.. maxNrofConfiguredGrantConfig-r16-1) + +-- TAG-CONFIGUREDGRANTCONFIGINDEX-STOP +-- TAG-CONFIGUREDGRANTCONFIGINDEXMAC-START + +ConfiguredGrantConfigIndexMAC-r16 ::= INTEGER (0.. maxNrofConfiguredGrantConfigMAC-r16-1) + +-- TAG-CONFIGUREDGRANTCONFIGINDEXMAC-STOP +-- TAG-CONNESTFAILURECONTROL-START + +ConnEstFailureControl ::= SEQUENCE { + connEstFailCount ENUMERATED {n1, n2, n3, n4}, + connEstFailOffsetValidity ENUMERATED {s30, s60, s120, s240, s300, s420, s600, s900}, + connEstFailOffset INTEGER (0..15) OPTIONAL -- Need S +} + +-- TAG-CONNESTFAILURECONTROL-STOP +-- TAG-CONTROLRESOURCESET-START + +ControlResourceSet ::= SEQUENCE { + controlResourceSetId ControlResourceSetId, + + frequencyDomainResources BIT STRING (SIZE (45)), + duration INTEGER (1..maxCoReSetDuration), + cce-REG-MappingType CHOICE { + interleaved SEQUENCE { + reg-BundleSize ENUMERATED {n2, n3, n6}, + interleaverSize ENUMERATED {n2, n3, n6}, + shiftIndex INTEGER(0..maxNrofPhysicalResourceBlocks-1) OPTIONAL -- Need S + }, + nonInterleaved NULL + }, + precoderGranularity ENUMERATED {sameAsREG-bundle, allContiguousRBs}, + tci-StatesPDCCH-ToAddList SEQUENCE(SIZE (1..maxNrofTCI-StatesPDCCH)) OF TCI-StateId OPTIONAL, -- Cond NotSIB1-initialBWP + tci-StatesPDCCH-ToReleaseList SEQUENCE(SIZE (1..maxNrofTCI-StatesPDCCH)) OF TCI-StateId OPTIONAL, -- Cond NotSIB1-initialBWP + tci-PresentInDCI ENUMERATED {enabled} OPTIONAL, -- Need S + pdcch-DMRS-ScramblingID INTEGER (0..65535) OPTIONAL, -- Need S + ..., + [[ + rb-Offset-r16 INTEGER (0..5) OPTIONAL, -- Need S + tci-PresentForDCI-Format1-2-r16 INTEGER (1..3) OPTIONAL, -- Need S + coresetPoolIndex-r16 INTEGER (0..1) OPTIONAL, -- Need S + controlResourceSetId-v1610 ControlResourceSetId-v1610 OPTIONAL -- Need S + ]] +} + +-- TAG-CONTROLRESOURCESET-STOP +-- TAG-CONTROLRESOURCESETID-START + +ControlResourceSetId ::= INTEGER (0..maxNrofControlResourceSets-1) + +ControlResourceSetId-r16 ::= INTEGER (0..maxNrofControlResourceSets-1-r16) + +ControlResourceSetId-v1610 ::= INTEGER (maxNrofControlResourceSets..maxNrofControlResourceSets-1-r16) + +-- TAG-CONTROLRESOURCESETID-STOP +-- TAG-CONTROLRESOURCESETZERO-START + +ControlResourceSetZero ::= INTEGER (0..15) + +-- TAG-CONTROLRESOURCESETZERO-STOP +-- TAG-CrossCarrierSchedulingConfig-START + +CrossCarrierSchedulingConfig ::= SEQUENCE { + schedulingCellInfo CHOICE { + own SEQUENCE { -- Cross carrier scheduling: scheduling cell + cif-Presence BOOLEAN + }, + other SEQUENCE { -- Cross carrier scheduling: scheduled cell + schedulingCellId ServCellIndex, + cif-InSchedulingCell INTEGER (1..7) + } + }, + ..., + [[ + carrierIndicatorSize SEQUENCE { + carrierIndicatorSizeForDCI-Format1-2-r16 INTEGER (0..3), + carrierIndicatorSizeForDCI-Format0-2-r16 INTEGER (0..3) + } OPTIONAL -- Cond CIF-PRESENCE + ]] +} + +-- TAG-CrossCarrierSchedulingConfig-STOP +-- TAG-CSI-APERIODICTRIGGERSTATELIST-START + +CSI-AperiodicTriggerStateList ::= SEQUENCE (SIZE (1..maxNrOfCSI-AperiodicTriggers)) OF CSI-AperiodicTriggerState + +CSI-AperiodicTriggerState ::= SEQUENCE { + associatedReportConfigInfoList SEQUENCE (SIZE(1..maxNrofReportConfigPerAperiodicTrigger)) OF CSI-AssociatedReportConfigInfo, + ... +} + +CSI-AssociatedReportConfigInfo ::= SEQUENCE { + reportConfigId CSI-ReportConfigId, + resourcesForChannel CHOICE { + nzp-CSI-RS SEQUENCE { + resourceSet INTEGER (1..maxNrofNZP-CSI-RS-ResourceSetsPerConfig), + qcl-info SEQUENCE (SIZE(1..maxNrofAP-CSI-RS-ResourcesPerSet)) OF TCI-StateId + OPTIONAL -- Cond Aperiodic + }, + csi-SSB-ResourceSet INTEGER (1..maxNrofCSI-SSB-ResourceSetsPerConfig) + }, + csi-IM-ResourcesForInterference INTEGER(1..maxNrofCSI-IM-ResourceSetsPerConfig) + OPTIONAL, -- Cond CSI-IM-ForInterference + nzp-CSI-RS-ResourcesForInterference INTEGER (1..maxNrofNZP-CSI-RS-ResourceSetsPerConfig) + OPTIONAL, -- Cond NZP-CSI-RS-ForInterference + ... +} + +-- TAG-CSI-APERIODICTRIGGERSTATELIST-STOP +-- TAG-CSI-FREQUENCYOCCUPATION-START + +CSI-FrequencyOccupation ::= SEQUENCE { + startingRB INTEGER (0..maxNrofPhysicalResourceBlocks-1), + nrofRBs INTEGER (24..maxNrofPhysicalResourceBlocksPlus1), + ... +} + +-- TAG-CSI-FREQUENCYOCCUPATION-STOP +-- TAG-CSI-IM-RESOURCE-START + +CSI-IM-Resource ::= SEQUENCE { + csi-IM-ResourceId CSI-IM-ResourceId, + csi-IM-ResourceElementPattern CHOICE { + pattern0 SEQUENCE { + subcarrierLocation-p0 ENUMERATED { s0, s2, s4, s6, s8, s10 }, + symbolLocation-p0 INTEGER (0..12) + }, + pattern1 SEQUENCE { + subcarrierLocation-p1 ENUMERATED { s0, s4, s8 }, + symbolLocation-p1 INTEGER (0..13) + } + } OPTIONAL, -- Need M + freqBand CSI-FrequencyOccupation OPTIONAL, -- Need M + periodicityAndOffset CSI-ResourcePeriodicityAndOffset OPTIONAL, -- Cond PeriodicOrSemiPersistent + ... +} + +-- TAG-CSI-IM-RESOURCE-STOP +-- TAG-CSI-IM-RESOURCEID-START + +CSI-IM-ResourceId ::= INTEGER (0..maxNrofCSI-IM-Resources-1) + +-- TAG-CSI-IM-RESOURCEID-STOP +-- TAG-CSI-IM-RESOURCESET-START + +CSI-IM-ResourceSet ::= SEQUENCE { + csi-IM-ResourceSetId CSI-IM-ResourceSetId, + csi-IM-Resources SEQUENCE (SIZE(1..maxNrofCSI-IM-ResourcesPerSet)) OF CSI-IM-ResourceId, + ... +} +-- TAG-CSI-IM-RESOURCESET-STOP +-- TAG-CSI-IM-RESOURCESETID-START + +CSI-IM-ResourceSetId ::= INTEGER (0..maxNrofCSI-IM-ResourceSets-1) + +-- TAG-CSI-IM-RESOURCESETID-STOP +-- TAG-CSI-MEASCONFIG-START + +CSI-MeasConfig ::= SEQUENCE { + nzp-CSI-RS-ResourceToAddModList SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-Resources)) OF NZP-CSI-RS-Resource OPTIONAL, -- Need N + nzp-CSI-RS-ResourceToReleaseList SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-Resources)) OF NZP-CSI-RS-ResourceId OPTIONAL, -- Need N + nzp-CSI-RS-ResourceSetToAddModList SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-ResourceSets)) OF NZP-CSI-RS-ResourceSet + OPTIONAL, -- Need N + nzp-CSI-RS-ResourceSetToReleaseList SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-ResourceSets)) OF NZP-CSI-RS-ResourceSetId + OPTIONAL, -- Need N + csi-IM-ResourceToAddModList SEQUENCE (SIZE (1..maxNrofCSI-IM-Resources)) OF CSI-IM-Resource OPTIONAL, -- Need N + csi-IM-ResourceToReleaseList SEQUENCE (SIZE (1..maxNrofCSI-IM-Resources)) OF CSI-IM-ResourceId OPTIONAL, -- Need N + csi-IM-ResourceSetToAddModList SEQUENCE (SIZE (1..maxNrofCSI-IM-ResourceSets)) OF CSI-IM-ResourceSet OPTIONAL, -- Need N + csi-IM-ResourceSetToReleaseList SEQUENCE (SIZE (1..maxNrofCSI-IM-ResourceSets)) OF CSI-IM-ResourceSetId OPTIONAL, -- Need N + csi-SSB-ResourceSetToAddModList SEQUENCE (SIZE (1..maxNrofCSI-SSB-ResourceSets)) OF CSI-SSB-ResourceSet OPTIONAL, -- Need N + csi-SSB-ResourceSetToReleaseList SEQUENCE (SIZE (1..maxNrofCSI-SSB-ResourceSets)) OF CSI-SSB-ResourceSetId OPTIONAL, -- Need N + csi-ResourceConfigToAddModList SEQUENCE (SIZE (1..maxNrofCSI-ResourceConfigurations)) OF CSI-ResourceConfig + OPTIONAL, -- Need N + csi-ResourceConfigToReleaseList SEQUENCE (SIZE (1..maxNrofCSI-ResourceConfigurations)) OF CSI-ResourceConfigId + OPTIONAL, -- Need N + csi-ReportConfigToAddModList SEQUENCE (SIZE (1..maxNrofCSI-ReportConfigurations)) OF CSI-ReportConfig OPTIONAL, -- Need N + csi-ReportConfigToReleaseList SEQUENCE (SIZE (1..maxNrofCSI-ReportConfigurations)) OF CSI-ReportConfigId + OPTIONAL, -- Need N + reportTriggerSize INTEGER (0..6) OPTIONAL, -- Need M + aperiodicTriggerStateList SetupRelease { CSI-AperiodicTriggerStateList } OPTIONAL, -- Need M + semiPersistentOnPUSCH-TriggerStateList SetupRelease { CSI-SemiPersistentOnPUSCH-TriggerStateList } OPTIONAL, -- Need M + ..., + [[ + reportTriggerSizeForDCI-Format0-2-r16 INTEGER (0..6) OPTIONAL -- Need R + ]] +} + +-- TAG-CSI-MEASCONFIG-STOP +-- TAG-CSI-REPORTCONFIG-START + +CSI-ReportConfig ::= SEQUENCE { + reportConfigId CSI-ReportConfigId, + carrier ServCellIndex OPTIONAL, -- Need S + resourcesForChannelMeasurement CSI-ResourceConfigId, + csi-IM-ResourcesForInterference CSI-ResourceConfigId OPTIONAL, -- Need R + nzp-CSI-RS-ResourcesForInterference CSI-ResourceConfigId OPTIONAL, -- Need R + reportConfigType CHOICE { + periodic SEQUENCE { + reportSlotConfig CSI-ReportPeriodicityAndOffset, + pucch-CSI-ResourceList SEQUENCE (SIZE (1..maxNrofBWPs)) OF PUCCH-CSI-Resource + }, + semiPersistentOnPUCCH SEQUENCE { + reportSlotConfig CSI-ReportPeriodicityAndOffset, + pucch-CSI-ResourceList SEQUENCE (SIZE (1..maxNrofBWPs)) OF PUCCH-CSI-Resource + }, + semiPersistentOnPUSCH SEQUENCE { + reportSlotConfig ENUMERATED {sl5, sl10, sl20, sl40, sl80, sl160, sl320}, + reportSlotOffsetList SEQUENCE (SIZE (1.. maxNrofUL-Allocations)) OF INTEGER(0..32), + p0alpha P0-PUSCH-AlphaSetId + }, + aperiodic SEQUENCE { + reportSlotOffsetList SEQUENCE (SIZE (1..maxNrofUL-Allocations)) OF INTEGER(0..32) + } + }, + reportQuantity CHOICE { + none NULL, + cri-RI-PMI-CQI NULL, + cri-RI-i1 NULL, + cri-RI-i1-CQI SEQUENCE { + pdsch-BundleSizeForCSI ENUMERATED {n2, n4} OPTIONAL -- Need S + }, + cri-RI-CQI NULL, + cri-RSRP NULL, + ssb-Index-RSRP NULL, + cri-RI-LI-PMI-CQI NULL + }, + reportFreqConfiguration SEQUENCE { + cqi-FormatIndicator ENUMERATED { widebandCQI, subbandCQI } OPTIONAL, -- Need R + pmi-FormatIndicator ENUMERATED { widebandPMI, subbandPMI } OPTIONAL, -- Need R + csi-ReportingBand CHOICE { + subbands3 BIT STRING(SIZE(3)), + subbands4 BIT STRING(SIZE(4)), + subbands5 BIT STRING(SIZE(5)), + subbands6 BIT STRING(SIZE(6)), + subbands7 BIT STRING(SIZE(7)), + subbands8 BIT STRING(SIZE(8)), + subbands9 BIT STRING(SIZE(9)), + subbands10 BIT STRING(SIZE(10)), + subbands11 BIT STRING(SIZE(11)), + subbands12 BIT STRING(SIZE(12)), + subbands13 BIT STRING(SIZE(13)), + subbands14 BIT STRING(SIZE(14)), + subbands15 BIT STRING(SIZE(15)), + subbands16 BIT STRING(SIZE(16)), + subbands17 BIT STRING(SIZE(17)), + subbands18 BIT STRING(SIZE(18)), + ..., + subbands19-v1530 BIT STRING(SIZE(19)) + } OPTIONAL -- Need S + + } OPTIONAL, -- Need R + timeRestrictionForChannelMeasurements ENUMERATED {configured, notConfigured}, + timeRestrictionForInterferenceMeasurements ENUMERATED {configured, notConfigured}, + codebookConfig CodebookConfig OPTIONAL, -- Need R + dummy ENUMERATED {n1, n2} OPTIONAL, -- Need R + groupBasedBeamReporting CHOICE { + enabled NULL, + disabled SEQUENCE { + nrofReportedRS ENUMERATED {n1, n2, n3, n4} OPTIONAL -- Need S + } + }, + cqi-Table ENUMERATED {table1, table2, table3, spare1} OPTIONAL, -- Need R + subbandSize ENUMERATED {value1, value2}, + non-PMI-PortIndication SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-ResourcesPerConfig)) OF PortIndexFor8Ranks OPTIONAL, -- Need R + ..., + [[ + semiPersistentOnPUSCH-v1530 SEQUENCE { + reportSlotConfig-v1530 ENUMERATED {sl4, sl8, sl16} + } OPTIONAL -- Need R + ]], + [[ + semiPersistentOnPUSCH-v1610 SEQUENCE { + reportSlotOffsetListForDCI-Format0-2-r16 SEQUENCE (SIZE (1.. maxNrofUL-Allocations-r16)) OF INTEGER(0..32) + OPTIONAL, -- Need R + reportSlotOffsetListForDCI-Format0-1-r16 SEQUENCE (SIZE (1.. maxNrofUL-Allocations-r16)) OF INTEGER(0..32) + OPTIONAL -- Need R + } OPTIONAL, -- Need R + aperiodic-v1610 SEQUENCE { + reportSlotOffsetListForDCI-Format0-2-r16 SEQUENCE (SIZE (1.. maxNrofUL-Allocations-r16)) OF INTEGER(0..32) + OPTIONAL, -- Need R + reportSlotOffsetListForDCI-Format0-1-r16 SEQUENCE (SIZE (1.. maxNrofUL-Allocations-r16)) OF INTEGER(0..32) + OPTIONAL -- Need R + } OPTIONAL, -- Need R + reportQuantity-r16 CHOICE { + cri-SINR-r16 NULL, + ssb-Index-SINR-r16 NULL + } OPTIONAL, -- Need R + codebookConfig-r16 CodebookConfig-r16 OPTIONAL -- Need R + ]] +} + +CSI-ReportPeriodicityAndOffset ::= CHOICE { + slots4 INTEGER(0..3), + slots5 INTEGER(0..4), + slots8 INTEGER(0..7), + slots10 INTEGER(0..9), + slots16 INTEGER(0..15), + slots20 INTEGER(0..19), + slots40 INTEGER(0..39), + slots80 INTEGER(0..79), + slots160 INTEGER(0..159), + slots320 INTEGER(0..319) +} + +PUCCH-CSI-Resource ::= SEQUENCE { + uplinkBandwidthPartId BWP-Id, + pucch-Resource PUCCH-ResourceId +} + +PortIndexFor8Ranks ::= CHOICE { + portIndex8 SEQUENCE{ + rank1-8 PortIndex8 OPTIONAL, -- Need R + rank2-8 SEQUENCE(SIZE(2)) OF PortIndex8 OPTIONAL, -- Need R + rank3-8 SEQUENCE(SIZE(3)) OF PortIndex8 OPTIONAL, -- Need R + rank4-8 SEQUENCE(SIZE(4)) OF PortIndex8 OPTIONAL, -- Need R + rank5-8 SEQUENCE(SIZE(5)) OF PortIndex8 OPTIONAL, -- Need R + rank6-8 SEQUENCE(SIZE(6)) OF PortIndex8 OPTIONAL, -- Need R + rank7-8 SEQUENCE(SIZE(7)) OF PortIndex8 OPTIONAL, -- Need R + rank8-8 SEQUENCE(SIZE(8)) OF PortIndex8 OPTIONAL -- Need R + }, + portIndex4 SEQUENCE{ + rank1-4 PortIndex4 OPTIONAL, -- Need R + rank2-4 SEQUENCE(SIZE(2)) OF PortIndex4 OPTIONAL, -- Need R + rank3-4 SEQUENCE(SIZE(3)) OF PortIndex4 OPTIONAL, -- Need R + rank4-4 SEQUENCE(SIZE(4)) OF PortIndex4 OPTIONAL -- Need R + }, + portIndex2 SEQUENCE{ + rank1-2 PortIndex2 OPTIONAL, -- Need R + rank2-2 SEQUENCE(SIZE(2)) OF PortIndex2 OPTIONAL -- Need R + }, + portIndex1 NULL +} + +PortIndex8::= INTEGER (0..7) +PortIndex4::= INTEGER (0..3) +PortIndex2::= INTEGER (0..1) + +-- TAG-CSI-REPORTCONFIG-STOP +-- TAG-CSI-REPORTCONFIGID-START + +CSI-ReportConfigId ::= INTEGER (0..maxNrofCSI-ReportConfigurations-1) + +-- TAG-CSI-REPORTCONFIGID-STOP +-- TAG-CSI-RESOURCECONFIG-START + +CSI-ResourceConfig ::= SEQUENCE { + csi-ResourceConfigId CSI-ResourceConfigId, + csi-RS-ResourceSetList CHOICE { + nzp-CSI-RS-SSB SEQUENCE { + nzp-CSI-RS-ResourceSetList SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-ResourceSetsPerConfig)) OF NZP-CSI-RS-ResourceSetId OPTIONAL, -- Need R + csi-SSB-ResourceSetList SEQUENCE (SIZE (1..maxNrofCSI-SSB-ResourceSetsPerConfig)) OF CSI-SSB-ResourceSetId OPTIONAL -- Need R + }, + csi-IM-ResourceSetList SEQUENCE (SIZE (1..maxNrofCSI-IM-ResourceSetsPerConfig)) OF CSI-IM-ResourceSetId + }, + + bwp-Id BWP-Id, + resourceType ENUMERATED { aperiodic, semiPersistent, periodic }, + ... +} + +-- TAG-CSI-RESOURCECONFIG-STOP +-- TAG-CSI-RESOURCECONFIGID-START + +CSI-ResourceConfigId ::= INTEGER (0..maxNrofCSI-ResourceConfigurations-1) + +-- TAG-CSI-RESOURCECONFIGID-STOP +-- TAG-CSI-RESOURCEPERIODICITYANDOFFSET-START + +CSI-ResourcePeriodicityAndOffset ::= CHOICE { + slots4 INTEGER (0..3), + slots5 INTEGER (0..4), + slots8 INTEGER (0..7), + slots10 INTEGER (0..9), + slots16 INTEGER (0..15), + slots20 INTEGER (0..19), + slots32 INTEGER (0..31), + slots40 INTEGER (0..39), + slots64 INTEGER (0..63), + slots80 INTEGER (0..79), + slots160 INTEGER (0..159), + slots320 INTEGER (0..319), + slots640 INTEGER (0..639) +} + +-- TAG-CSI-RESOURCEPERIODICITYANDOFFSET-STOP +-- TAG-CSI-RS-RESOURCECONFIGMOBILITY-START + +CSI-RS-ResourceConfigMobility ::= SEQUENCE { + subcarrierSpacing SubcarrierSpacing, + csi-RS-CellList-Mobility SEQUENCE (SIZE (1..maxNrofCSI-RS-CellsRRM)) OF CSI-RS-CellMobility, + ..., + [[ + refServCellIndex ServCellIndex OPTIONAL -- Need S + ]] + + +} + +CSI-RS-CellMobility ::= SEQUENCE { + cellId PhysCellId, + csi-rs-MeasurementBW SEQUENCE { + nrofPRBs ENUMERATED { size24, size48, size96, size192, size264}, + startPRB INTEGER(0..2169) + }, + density ENUMERATED {d1,d3} OPTIONAL, -- Need R + csi-rs-ResourceList-Mobility SEQUENCE (SIZE (1..maxNrofCSI-RS-ResourcesRRM)) OF CSI-RS-Resource-Mobility +} + +CSI-RS-Resource-Mobility ::= SEQUENCE { + csi-RS-Index CSI-RS-Index, + slotConfig CHOICE { + ms4 INTEGER (0..31), + ms5 INTEGER (0..39), + ms10 INTEGER (0..79), + ms20 INTEGER (0..159), + ms40 INTEGER (0..319) + }, + associatedSSB SEQUENCE { + ssb-Index SSB-Index, + isQuasiColocated BOOLEAN + } OPTIONAL, -- Need R + frequencyDomainAllocation CHOICE { + row1 BIT STRING (SIZE (4)), + row2 BIT STRING (SIZE (12)) + }, + firstOFDMSymbolInTimeDomain INTEGER (0..13), + sequenceGenerationConfig INTEGER (0..1023), + ... +} + +CSI-RS-Index ::= INTEGER (0..maxNrofCSI-RS-ResourcesRRM-1) + +-- TAG-CSI-RS-RESOURCECONFIGMOBILITY-STOP +-- TAG-CSI-RS-RESOURCEMAPPING-START + +CSI-RS-ResourceMapping ::= SEQUENCE { + frequencyDomainAllocation CHOICE { + row1 BIT STRING (SIZE (4)), + row2 BIT STRING (SIZE (12)), + row4 BIT STRING (SIZE (3)), + other BIT STRING (SIZE (6)) + }, + nrofPorts ENUMERATED {p1,p2,p4,p8,p12,p16,p24,p32}, + firstOFDMSymbolInTimeDomain INTEGER (0..13), + firstOFDMSymbolInTimeDomain2 INTEGER (2..12) OPTIONAL, -- Need R + cdm-Type ENUMERATED {noCDM, fd-CDM2, cdm4-FD2-TD2, cdm8-FD2-TD4}, + density CHOICE { + dot5 ENUMERATED {evenPRBs, oddPRBs}, + one NULL, + three NULL, + spare NULL + }, + freqBand CSI-FrequencyOccupation, + ... +} + +-- TAG-CSI-RS-RESOURCEMAPPING-STOP +-- TAG-CSI-SEMIPERSISTENTONPUSCHTRIGGERSTATELIST-START + +CSI-SemiPersistentOnPUSCH-TriggerStateList ::= SEQUENCE(SIZE (1..maxNrOfSemiPersistentPUSCH-Triggers)) OF CSI-SemiPersistentOnPUSCH-TriggerState + +CSI-SemiPersistentOnPUSCH-TriggerState ::= SEQUENCE { + associatedReportConfigInfo CSI-ReportConfigId, + ... +} + +-- TAG-CSI-SEMIPERSISTENTONPUSCHTRIGGERSTATELIST-STOP +-- TAG-CSI-SSB-RESOURCESET-START + +CSI-SSB-ResourceSet ::= SEQUENCE { + csi-SSB-ResourceSetId CSI-SSB-ResourceSetId, + csi-SSB-ResourceList SEQUENCE (SIZE(1..maxNrofCSI-SSB-ResourcePerSet)) OF SSB-Index, + ... +} + +-- TAG-CSI-SSB-RESOURCESET-STOP +-- TAG-CSI-SSB-RESOURCESETID-START + +CSI-SSB-ResourceSetId ::= INTEGER (0..maxNrofCSI-SSB-ResourceSets-1) + +-- TAG-CSI-SSB-RESOURCESETID-STOP +-- TAG-DEDICATED-NAS-MESSAGE-START + +DedicatedNAS-Message ::= OCTET STRING + +-- TAG-DEDICATED-NAS-MESSAGE-STOP +-- TAG-DMRS-DOWNLINKCONFIG-START + +DMRS-DownlinkConfig ::= SEQUENCE { + dmrs-Type ENUMERATED {type2} OPTIONAL, -- Need S + dmrs-AdditionalPosition ENUMERATED {pos0, pos1, pos3} OPTIONAL, -- Need S + maxLength ENUMERATED {len2} OPTIONAL, -- Need S + scramblingID0 INTEGER (0..65535) OPTIONAL, -- Need S + scramblingID1 INTEGER (0..65535) OPTIONAL, -- Need S + phaseTrackingRS SetupRelease { PTRS-DownlinkConfig } OPTIONAL, -- Need M + ..., + [[ + dmrs-Downlink-r16 ENUMERATED {enabled} OPTIONAL -- Need R + ]] + +} + +-- TAG-DMRS-DOWNLINKCONFIG-STOP +-- TAG-DMRS-UPLINKCONFIG-START + +DMRS-UplinkConfig ::= SEQUENCE { + dmrs-Type ENUMERATED {type2} OPTIONAL, -- Need S + dmrs-AdditionalPosition ENUMERATED {pos0, pos1, pos3} OPTIONAL, -- Need S + phaseTrackingRS SetupRelease { PTRS-UplinkConfig } OPTIONAL, -- Need M + maxLength ENUMERATED {len2} OPTIONAL, -- Need S + transformPrecodingDisabled SEQUENCE { + scramblingID0 INTEGER (0..65535) OPTIONAL, -- Need S + scramblingID1 INTEGER (0..65535) OPTIONAL, -- Need S + ..., + [[ + dmrs-Uplink-r16 ENUMERATED {enabled} OPTIONAL -- Need R + ]] + } OPTIONAL, -- Need R + transformPrecodingEnabled SEQUENCE { + nPUSCH-Identity INTEGER(0..1007) OPTIONAL, -- Need S + sequenceGroupHopping ENUMERATED {disabled} OPTIONAL, -- Need S + sequenceHopping ENUMERATED {enabled} OPTIONAL, -- Need S + ..., + [[ + dmrs-UplinkTransformPrecoding-r16 SetupRelease {DMRS-UplinkTransformPrecoding-r16} OPTIONAL -- Need M + ]] + } OPTIONAL, -- Need R + ... +} + +DMRS-UplinkTransformPrecoding-r16 ::= SEQUENCE { + pi2BPSK-ScramblingID0 INTEGER(0..65535) OPTIONAL, -- Need S + pi2BPSK-ScramblingID1 INTEGER(0..65535) OPTIONAL -- Need S +} + +-- TAG-DMRS-UPLINKCONFIG-STOP +-- TAG-DOWNLINKCONFIGCOMMON-START + +DownlinkConfigCommon ::= SEQUENCE { + frequencyInfoDL FrequencyInfoDL OPTIONAL, -- Cond InterFreqHOAndServCellAdd + initialDownlinkBWP BWP-DownlinkCommon OPTIONAL, -- Cond ServCellAdd + ... +} + +-- TAG-DOWNLINKCONFIGCOMMON-STOP +-- TAG-DOWNLINKCONFIGCOMMONSIB-START + +DownlinkConfigCommonSIB ::= SEQUENCE { + frequencyInfoDL FrequencyInfoDL-SIB, + initialDownlinkBWP BWP-DownlinkCommon, + bcch-Config BCCH-Config, + pcch-Config PCCH-Config, + ... +} + + +BCCH-Config ::= SEQUENCE { + modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16}, + ... +} + + +PCCH-Config ::= SEQUENCE { + defaultPagingCycle PagingCycle, + nAndPagingFrameOffset CHOICE { + oneT NULL, + halfT INTEGER (0..1), + quarterT INTEGER (0..3), + oneEighthT INTEGER (0..7), + oneSixteenthT INTEGER (0..15) + }, + ns ENUMERATED {four, two, one}, + firstPDCCH-MonitoringOccasionOfPO CHOICE { + sCS15KHZoneT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..139), + sCS30KHZoneT-SCS15KHZhalfT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..279), + sCS60KHZoneT-SCS30KHZhalfT-SCS15KHZquarterT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..559), + sCS120KHZoneT-SCS60KHZhalfT-SCS30KHZquarterT-SCS15KHZoneEighthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..1119), + sCS120KHZhalfT-SCS60KHZquarterT-SCS30KHZoneEighthT-SCS15KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..2239), + sCS120KHZquarterT-SCS60KHZoneEighthT-SCS30KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..4479), + sCS120KHZoneEighthT-SCS60KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..8959), + sCS120KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..17919) + } OPTIONAL, -- Need R + ..., + [[ + nrofPDCCH-MonitoringOccasionPerSSB-InPO-r16 INTEGER (2..4) OPTIONAL -- Cond SharedSpectrum2 + ]] +} + +-- TAG-DOWNLINKCONFIGCOMMONSIB-STOP +-- TAG-DOWNLINKPREEMPTION-START + +DownlinkPreemption ::= SEQUENCE { + int-RNTI RNTI-Value, + timeFrequencySet ENUMERATED {set0, set1}, + dci-PayloadSize INTEGER (0..maxINT-DCI-PayloadSize), + int-ConfigurationPerServingCell SEQUENCE (SIZE (1..maxNrofServingCells)) OF INT-ConfigurationPerServingCell, + ... +} + +INT-ConfigurationPerServingCell ::= SEQUENCE { + servingCellId ServCellIndex, + positionInDCI INTEGER (0..maxINT-DCI-PayloadSize-1) +} + +-- TAG-DOWNLINKPREEMPTION-STOP +-- TAG-DRB-IDENTITY-START + +DRB-Identity ::= INTEGER (1..32) + +-- TAG-DRB-IDENTITY-STOP +-- TAG-DRX-CONFIG-START + +DRX-Config ::= SEQUENCE { + drx-onDurationTimer CHOICE { + subMilliSeconds INTEGER (1..31), + milliSeconds ENUMERATED { + ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40, ms50, ms60, + ms80, ms100, ms200, ms300, ms400, ms500, ms600, ms800, ms1000, ms1200, + ms1600, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 } + }, + drx-InactivityTimer ENUMERATED { + ms0, ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40, ms50, ms60, ms80, + ms100, ms200, ms300, ms500, ms750, ms1280, ms1920, ms2560, spare9, spare8, + spare7, spare6, spare5, spare4, spare3, spare2, spare1}, + drx-HARQ-RTT-TimerDL INTEGER (0..56), + drx-HARQ-RTT-TimerUL INTEGER (0..56), + drx-RetransmissionTimerDL ENUMERATED { + sl0, sl1, sl2, sl4, sl6, sl8, sl16, sl24, sl33, sl40, sl64, sl80, sl96, sl112, sl128, + sl160, sl320, spare15, spare14, spare13, spare12, spare11, spare10, spare9, + spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1}, + drx-RetransmissionTimerUL ENUMERATED { + sl0, sl1, sl2, sl4, sl6, sl8, sl16, sl24, sl33, sl40, sl64, sl80, sl96, sl112, sl128, + sl160, sl320, spare15, spare14, spare13, spare12, spare11, spare10, spare9, + spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 }, + drx-LongCycleStartOffset CHOICE { + ms10 INTEGER(0..9), + ms20 INTEGER(0..19), + ms32 INTEGER(0..31), + ms40 INTEGER(0..39), + ms60 INTEGER(0..59), + ms64 INTEGER(0..63), + ms70 INTEGER(0..69), + ms80 INTEGER(0..79), + ms128 INTEGER(0..127), + ms160 INTEGER(0..159), + ms256 INTEGER(0..255), + ms320 INTEGER(0..319), + ms512 INTEGER(0..511), + ms640 INTEGER(0..639), + ms1024 INTEGER(0..1023), + ms1280 INTEGER(0..1279), + ms2048 INTEGER(0..2047), + ms2560 INTEGER(0..2559), + ms5120 INTEGER(0..5119), + ms10240 INTEGER(0..10239) + }, + shortDRX SEQUENCE { + drx-ShortCycle ENUMERATED { + ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, + ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, spare9, + spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 }, + drx-ShortCycleTimer INTEGER (1..16) + } OPTIONAL, -- Need R + drx-SlotOffset INTEGER (0..31) +} + +-- TAG-DRX-CONFIG-STOP +-- TAG-DRX-CONFIGSECONDARYGROUP-START + +DRX-ConfigSecondaryGroup ::= SEQUENCE { + drx-onDurationTimer CHOICE { + subMilliSeconds INTEGER (1..31), + milliSeconds ENUMERATED { + ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40, ms50, ms60, + ms80, ms100, ms200, ms300, ms400, ms500, ms600, ms800, ms1000, ms1200, + ms1600, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 } + }, + drx-InactivityTimer ENUMERATED { + ms0, ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40, ms50, ms60, ms80, + ms100, ms200, ms300, ms500, ms750, ms1280, ms1920, ms2560, spare9, spare8, + spare7, spare6, spare5, spare4, spare3, spare2, spare1} +} + +-- TAG-DRX-CONFIGSECONDARYGROUP-STOP +-- TAG-FILTERCOEFFICIENT-START + +FilterCoefficient ::= ENUMERATED { fc0, fc1, fc2, fc3, fc4, fc5, fc6, fc7, fc8, fc9, fc11, fc13, fc15, fc17, fc19, spare1, ...} + +-- TAG-FILTERCOEFFICIENT-STOP +-- TAG-FREQBANDINDICATORNR-START + +FreqBandIndicatorNR ::= INTEGER (1..1024) + +-- TAG-FREQBANDINDICATORNR-STOP +-- TAG-FREQUENCYINFODL-START + +FrequencyInfoDL ::= SEQUENCE { + absoluteFrequencySSB ARFCN-ValueNR OPTIONAL, -- Cond SpCellAdd + frequencyBandList MultiFrequencyBandListNR, + absoluteFrequencyPointA ARFCN-ValueNR, + scs-SpecificCarrierList SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier, + ... +} + +-- TAG-FREQUENCYINFODL-STOP +-- TAG-FREQUENCYINFODL-SIB-START + +FrequencyInfoDL-SIB ::= SEQUENCE { + frequencyBandList MultiFrequencyBandListNR-SIB, + offsetToPointA INTEGER (0..2199), + scs-SpecificCarrierList SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier +} + +-- TAG-FREQUENCYINFODL-SIB-STOP +-- TAG-FREQUENCYINFOUL-START + +FrequencyInfoUL ::= SEQUENCE { + frequencyBandList MultiFrequencyBandListNR OPTIONAL, -- Cond FDD-OrSUL + absoluteFrequencyPointA ARFCN-ValueNR OPTIONAL, -- Cond FDD-OrSUL + scs-SpecificCarrierList SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier, + additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Need S + p-Max P-Max OPTIONAL, -- Need S + frequencyShift7p5khz ENUMERATED {true} OPTIONAL, -- Cond FDD-TDD-OrSUL-Optional + ... +} + +-- TAG-FREQUENCYINFOUL-STOP +-- TAG-FREQUENCYINFOUL-SIB-START + +FrequencyInfoUL-SIB ::= SEQUENCE { + frequencyBandList MultiFrequencyBandListNR-SIB OPTIONAL, -- Cond FDD-OrSUL + absoluteFrequencyPointA ARFCN-ValueNR OPTIONAL, -- Cond FDD-OrSUL + scs-SpecificCarrierList SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier, + p-Max P-Max OPTIONAL, -- Need S + frequencyShift7p5khz ENUMERATED {true} OPTIONAL, -- Cond FDD-TDD-OrSUL-Optional + ... +} + +-- TAG-FREQUENCYINFOUL-SIB-STOP +-- TAG-HIGHSPEEDCONFIG-START + +HighSpeedConfig-r16 ::= SEQUENCE { + highSpeedMeasFlag-r16 ENUMERATED {true} OPTIONAL, -- Need R + highSpeedDemodFlag-r16 ENUMERATED {true} OPTIONAL, -- Need R + ... +} + +-- TAG-HIGHSPEEDCONFIG-STOP +-- TAG-HYSTERESIS-START + +Hysteresis ::= INTEGER (0..30) + +-- TAG-HYSTERESIS-STOP +-- TAG-INVALIDSYMBOLPATTERN-START + +InvalidSymbolPattern-r16 ::= SEQUENCE { + symbols-r16 CHOICE { + oneSlot BIT STRING (SIZE (14)), + twoSlots BIT STRING (SIZE (28)) + }, + periodicityAndPattern-r16 CHOICE { + n2 BIT STRING (SIZE (2)), + n4 BIT STRING (SIZE (4)), + n5 BIT STRING (SIZE (5)), + n8 BIT STRING (SIZE (8)), + n10 BIT STRING (SIZE (10)), + n20 BIT STRING (SIZE (20)), + n40 BIT STRING (SIZE (40)) + } OPTIONAL, -- Need M + ... +} + +-- TAG-INVALIDSYMBOLPATTERN-STOP +-- TAG-I-RNTI-VALUE-START + +I-RNTI-Value ::= BIT STRING (SIZE(40)) + +-- TAG-I-RNTI-VALUE-STOP +-- TAG-LBT-FAILURERECOVERYCONFIG-START + +LBT-FailureRecoveryConfig-r16 ::= SEQUENCE { + lbt-FailureInstanceMaxCount-r16 ENUMERATED {n4, n8, n16, n32, n64, n128}, + lbt-FailureDetectionTimer-r16 ENUMERATED {ms10, ms20, ms40, ms80, ms160, ms320}, + ... +} + +-- TAG-LBT-FAILURERECOVERYCONFIG-STOP +-- TAG-LOCATIONINFO-START + +LocationInfo-r16 ::= SEQUENCE { + commonLocationInfo-r16 CommonLocationInfo-r16 OPTIONAL, + bt-LocationInfo-r16 LogMeasResultListBT-r16 OPTIONAL, + wlan-LocationInfo-r16 LogMeasResultListWLAN-r16 OPTIONAL, + sensor-LocationInfo-r16 Sensor-LocationInfo-r16 OPTIONAL, + ... +} + +-- TAG-LOCATIONINFO-STOP +-- TAG-LOCATIONMEASUREMENTINFO-START + +LocationMeasurementInfo ::= CHOICE { + eutra-RSTD EUTRA-RSTD-InfoList, + ..., + eutra-FineTimingDetection NULL, + nr-PRS-Measurement-r16 NR-PRS-MeasurementInfoList-r16 +} + +EUTRA-RSTD-InfoList ::= SEQUENCE (SIZE (1..maxInterRAT-RSTD-Freq)) OF EUTRA-RSTD-Info + +EUTRA-RSTD-Info ::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + measPRS-Offset INTEGER (0..39), + ... +} + +NR-PRS-MeasurementInfoList-r16 ::= SEQUENCE (SIZE (1..maxFreqLayers)) OF NR-PRS-MeasurementInfo-r16 + +NR-PRS-MeasurementInfo-r16 ::= SEQUENCE { + dl-PRS-ARFCN-PointA-r16 ARFCN-ValueNR, + nr-MeasPRS-RepetitionAndOffset-r16 CHOICE { + ms20-r16 INTEGER (0..19), + ms40-r16 INTEGER (0..39), + ms80-r16 INTEGER (0..79), + ms160-r16 INTEGER (0..159), + ... + }, + nr-MeasPRS-length-r16 ENUMERATED {ms1dot5, ms3, ms3dot5, ms4, ms5dot5, ms6, spare2, spare1}, + ... +} + +-- TAG-LOCATIONMEASUREMENTINFO-STOP +-- TAG-LOGICALCHANNELCONFIG-START + +LogicalChannelConfig ::= SEQUENCE { + ul-SpecificParameters SEQUENCE { + priority INTEGER (1..16), + prioritisedBitRate ENUMERATED {kBps0, kBps8, kBps16, kBps32, kBps64, kBps128, kBps256, kBps512, + kBps1024, kBps2048, kBps4096, kBps8192, kBps16384, kBps32768, kBps65536, infinity}, + bucketSizeDuration ENUMERATED {ms5, ms10, ms20, ms50, ms100, ms150, ms300, ms500, ms1000, + spare7, spare6, spare5, spare4, spare3,spare2, spare1}, + allowedServingCells SEQUENCE (SIZE (1..maxNrofServingCells-1)) OF ServCellIndex + OPTIONAL, -- PDCP-CADuplication + allowedSCS-List SEQUENCE (SIZE (1..maxSCSs)) OF SubcarrierSpacing OPTIONAL, -- Need R + maxPUSCH-Duration ENUMERATED {ms0p02, ms0p04, ms0p0625, ms0p125, ms0p25, ms0p5, spare2, spare1} + OPTIONAL, -- Need R + configuredGrantType1Allowed ENUMERATED {true} OPTIONAL, -- Need R + logicalChannelGroup INTEGER (0..maxLCG-ID) OPTIONAL, -- Need R + schedulingRequestID SchedulingRequestId OPTIONAL, -- Need R + logicalChannelSR-Mask BOOLEAN, + logicalChannelSR-DelayTimerApplied BOOLEAN, + ..., + bitRateQueryProhibitTimer ENUMERATED {s0, s0dot4, s0dot8, s1dot6, s3, s6, s12, s30} OPTIONAL, -- Need R + [[ + allowedCG-List-r16 SEQUENCE (SIZE (0.. maxNrofConfiguredGrantConfigMAC-r16-1)) OF ConfiguredGrantConfigIndexMAC-r16 + OPTIONAL, -- Need S + allowedPHY-PriorityIndex-r16 ENUMERATED {p0, p1} OPTIONAL -- Need S + ]] + } OPTIONAL, -- Cond UL + ..., + [[ + channelAccessPriority-r16 INTEGER (1..4) OPTIONAL, -- Need R + bitRateMultiplier-r16 ENUMERATED {x40, x70, x100, x200} OPTIONAL -- Need R + ]] +} + +-- TAG-LOGICALCHANNELCONFIG-STOP +-- TAG-LOGICALCHANNELIDENTITY-START + +LogicalChannelIdentity ::= INTEGER (1..maxLC-ID) + +-- TAG-LOGICALCHANNELIDENTITY-STOP +-- TAG-MAC-CELLGROUPCONFIG-START + +MAC-CellGroupConfig ::= SEQUENCE { + drx-Config SetupRelease { DRX-Config } OPTIONAL, -- Need M + schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need M + bsr-Config BSR-Config OPTIONAL, -- Need M + tag-Config TAG-Config OPTIONAL, -- Need M + phr-Config SetupRelease { PHR-Config } OPTIONAL, -- Need M + skipUplinkTxDynamic BOOLEAN, + ..., + [[ + csi-Mask BOOLEAN OPTIONAL, -- Need M + dataInactivityTimer SetupRelease { DataInactivityTimer } OPTIONAL -- Cond MCG-Only + ]], + [[ + usePreBSR-r16 ENUMERATED {true} OPTIONAL, -- Need R + schedulingRequestID-LBT-SCell-r16 SchedulingRequestId OPTIONAL, -- Need M + lch-BasedPrioritization-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + schedulingRequestID-BFR-SCell-r16 SchedulingRequestId OPTIONAL, -- Need R + drx-ConfigSecondaryGroup-r16 SetupRelease { DRX-ConfigSecondaryGroup } OPTIONAL -- Need M + ]] +} + +DataInactivityTimer ::= ENUMERATED {s1, s2, s3, s5, s7, s10, s15, s20, s40, s50, s60, s80, s100, s120, s150, s180} + +-- TAG-MAC-CELLGROUPCONFIG-STOP +-- TAG-MEASCONFIG-START + +MeasConfig ::= SEQUENCE { + measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need N + measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need N + reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need N + reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need N + measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need N + measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need N + s-MeasureConfig CHOICE { + ssb-RSRP RSRP-Range, + csi-RSRP RSRP-Range + } OPTIONAL, -- Need M + quantityConfig QuantityConfig OPTIONAL, -- Need M + measGapConfig MeasGapConfig OPTIONAL, -- Need M + measGapSharingConfig MeasGapSharingConfig OPTIONAL, -- Need M + ..., + [[ + interFrequencyConfig-NoGap-r16 ENUMERATED {true} OPTIONAL -- Need R + ]] +} + +MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxNrofObjectId)) OF MeasObjectId + +MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxNrofMeasId)) OF MeasId + +ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId + +-- TAG-MEASCONFIG-STOP +-- TAG-MEASGAPCONFIG-START + +MeasGapConfig ::= SEQUENCE { + gapFR2 SetupRelease { GapConfig } OPTIONAL, -- Need M + ..., + [[ + gapFR1 SetupRelease { GapConfig } OPTIONAL, -- Need M + gapUE SetupRelease { GapConfig } OPTIONAL -- Need M + ]] + +} + +GapConfig ::= SEQUENCE { + gapOffset INTEGER (0..159), + mgl ENUMERATED {ms1dot5, ms3, ms3dot5, ms4, ms5dot5, ms6}, + mgrp ENUMERATED {ms20, ms40, ms80, ms160}, + mgta ENUMERATED {ms0, ms0dot25, ms0dot5}, + ..., + [[ + refServCellIndicator ENUMERATED {pCell, pSCell, mcg-FR2} OPTIONAL -- Cond NEDCorNRDC + ]], + [[ + refFR2ServCellAsyncCA-r16 ServCellIndex OPTIONAL -- Cond AsyncCA + ]] + +} + +-- TAG-MEASGAPCONFIG-STOP +-- TAG-MEASGAPSHARINGCONFIG-START + +MeasGapSharingConfig ::= SEQUENCE { + gapSharingFR2 SetupRelease { MeasGapSharingScheme } OPTIONAL, -- Need M + ..., + [[ + gapSharingFR1 SetupRelease { MeasGapSharingScheme } OPTIONAL, --Need M + gapSharingUE SetupRelease { MeasGapSharingScheme } OPTIONAL --Need M + ]] + +} + +MeasGapSharingScheme::= ENUMERATED {scheme00, scheme01, scheme10, scheme11} + +-- TAG-MEASGAPSHARINGCONFIG-STOP +-- TAG-MEASID-START + +MeasId ::= INTEGER (1..maxNrofMeasId) + +-- TAG-MEASID-STOP +-- TAG-MEASIDLECONFIG-START + +MeasIdleConfigSIB-r16 ::= SEQUENCE { + measIdleCarrierListNR-r16 SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF MeasIdleCarrierNR-r16 OPTIONAL, -- Need S + measIdleCarrierListEUTRA-r16 SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF MeasIdleCarrierEUTRA-r16 OPTIONAL, -- Need S + ... +} + +MeasIdleConfigDedicated-r16 ::= SEQUENCE { + measIdleCarrierListNR-r16 SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF MeasIdleCarrierNR-r16 OPTIONAL, -- Need N + measIdleCarrierListEUTRA-r16 SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF MeasIdleCarrierEUTRA-r16 OPTIONAL, -- Need N + measIdleDuration-r16 ENUMERATED{sec10, sec30, sec60, sec120, sec180, sec240, sec300, spare}, + validityAreaList-r16 ValidityAreaList-r16 OPTIONAL, -- Need N + ... +} + +ValidityAreaList-r16 ::= SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF ValidityArea-r16 + +ValidityArea-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueNR, + validityCellList-r16 ValidityCellList OPTIONAL -- Need N +} + +ValidityCellList ::= SEQUENCE (SIZE (1.. maxCellMeasIdle-r16)) OF PCI-Range + +MeasIdleCarrierNR-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueNR, + ssbSubcarrierSpacing-r16 SubcarrierSpacing, + frequencyBandList MultiFrequencyBandListNR OPTIONAL, -- Need R + measCellListNR-r16 CellListNR-r16 OPTIONAL, -- Need R + reportQuantities-r16 ENUMERATED {rsrp, rsrq, both}, + qualityThreshold-r16 SEQUENCE { + idleRSRP-Threshold-NR-r16 RSRP-Range OPTIONAL, -- Need R + idleRSRQ-Threshold-NR-r16 RSRQ-Range OPTIONAL -- Need R + } OPTIONAL, -- Need R + ssb-MeasConfig-r16 SEQUENCE { + nrofSS-BlocksToAverage-r16 INTEGER (2..maxNrofSS-BlocksToAverage) OPTIONAL, -- Need S + absThreshSS-BlocksConsolidation-r16 ThresholdNR OPTIONAL, -- Need S + smtc-r16 SSB-MTC OPTIONAL, -- Need S + ssb-ToMeasure-r16 SSB-ToMeasure OPTIONAL, -- Need S + deriveSSB-IndexFromCell-r16 BOOLEAN, + ss-RSSI-Measurement-r16 SS-RSSI-Measurement OPTIONAL -- Need S + } OPTIONAL, -- Need S + beamMeasConfigIdle-r16 BeamMeasConfigIdle-NR-r16 OPTIONAL, -- Need R + ... +} + +MeasIdleCarrierEUTRA-r16 ::= SEQUENCE { + carrierFreqEUTRA-r16 ARFCN-ValueEUTRA, + allowedMeasBandwidth-r16 EUTRA-AllowedMeasBandwidth, + measCellListEUTRA-r16 CellListEUTRA-r16 OPTIONAL, -- Need R + reportQuantitiesEUTRA-r16 ENUMERATED {rsrp, rsrq, both}, + qualityThresholdEUTRA-r16 SEQUENCE { + idleRSRP-Threshold-EUTRA-r16 RSRP-RangeEUTRA OPTIONAL, -- Need R + idleRSRQ-Threshold-EUTRA-r16 RSRQ-RangeEUTRA-r16 OPTIONAL -- Need R + } OPTIONAL, -- Need S + ... +} + +CellListNR-r16 ::= SEQUENCE (SIZE (1..maxCellMeasIdle-r16)) OF PCI-Range + +CellListEUTRA-r16 ::= SEQUENCE (SIZE (1..maxCellMeasIdle-r16)) OF EUTRA-PhysCellIdRange + +BeamMeasConfigIdle-NR-r16 ::= SEQUENCE { + reportQuantityRS-Indexes-r16 ENUMERATED {rsrp, rsrq, both}, + maxNrofRS-IndexesToReport-r16 INTEGER (1.. maxNrofIndexesToReport), + includeBeamMeasurements-r16 BOOLEAN +} + +RSRQ-RangeEUTRA-r16 ::= INTEGER (-30..46) + +-- TAG-MEASIDLECONFIG-STOP +-- TAG-MEASIDTOADDMODLIST-START + +MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxNrofMeasId)) OF MeasIdToAddMod + +MeasIdToAddMod ::= SEQUENCE { + measId MeasId, + measObjectId MeasObjectId, + reportConfigId ReportConfigId +} + +-- TAG-MEASIDTOADDMODLIST-STOP +-- TAG-MEASOBJECTCLI-START + +MeasObjectCLI-r16 ::= SEQUENCE { + cli-ResourceConfig-r16 CLI-ResourceConfig-r16, + ... +} + +CLI-ResourceConfig-r16 ::= SEQUENCE { + srs-ResourceConfig-r16 SetupRelease { SRS-ResourceListConfigCLI-r16 } OPTIONAL, -- Need M + rssi-ResourceConfig-r16 SetupRelease { RSSI-ResourceListConfigCLI-r16 } OPTIONAL -- Need M +} + +SRS-ResourceListConfigCLI-r16 ::= SEQUENCE (SIZE (1.. maxNrofCLI-SRS-Resources-r16)) OF SRS-ResourceConfigCLI-r16 + +RSSI-ResourceListConfigCLI-r16 ::= SEQUENCE (SIZE (1.. maxNrofCLI-RSSI-Resources-r16)) OF RSSI-ResourceConfigCLI-r16 + +SRS-ResourceConfigCLI-r16 ::= SEQUENCE { + srs-Resource-r16 SRS-Resource, + srs-SCS-r16 SubcarrierSpacing, + ... +} + +RSSI-ResourceConfigCLI-r16 ::= SEQUENCE { + rssi-ResourceId-r16 RSSI-ResourceId-r16, + rssi-SCS-r16 SubcarrierSpacing, + startPRB-r16 INTEGER (0..2169), + nrofPRBs-r16 INTEGER (4..maxNrofPhysicalResourceBlocksPlus1), + startPosition-r16 INTEGER (0..13), + nrofSymbols-r16 INTEGER (1..14), + rssi-PeriodicityAndOffset-r16 RSSI-PeriodicityAndOffset-r16, + ... +} + +RSSI-ResourceId-r16 ::= INTEGER (0.. maxNrofCLI-RSSI-Resources-r16-1) + +RSSI-PeriodicityAndOffset-r16 ::= CHOICE { + sl10 INTEGER(0..9), + sl20 INTEGER(0..19), + sl40 INTEGER(0..39), + sl80 INTEGER(0..79), + sl160 INTEGER(0..159), + sl320 INTEGER(0..319), + s1640 INTEGER(0..639), + ... +} + +-- TAG-MEASOBJECTCLI-STOP +-- TAG-MEASOBJECTEUTRA-START + +MeasObjectEUTRA::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + allowedMeasBandwidth EUTRA-AllowedMeasBandwidth, + cellsToRemoveListEUTRAN EUTRA-CellIndexList OPTIONAL, -- Need N + cellsToAddModListEUTRAN SEQUENCE (SIZE (1..maxCellMeasEUTRA)) OF EUTRA-Cell OPTIONAL, -- Need N + blackCellsToRemoveListEUTRAN EUTRA-CellIndexList OPTIONAL, -- Need N + blackCellsToAddModListEUTRAN SEQUENCE (SIZE (1..maxCellMeasEUTRA)) OF EUTRA-BlackCell OPTIONAL, -- Need N + eutra-PresenceAntennaPort1 EUTRA-PresenceAntennaPort1, + eutra-Q-OffsetRange EUTRA-Q-OffsetRange OPTIONAL, -- Need R + widebandRSRQ-Meas BOOLEAN, + ... +} + +EUTRA-CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeasEUTRA)) OF EUTRA-CellIndex + +EUTRA-CellIndex ::= INTEGER (1..maxCellMeasEUTRA) + + +EUTRA-Cell ::= SEQUENCE { + cellIndexEUTRA EUTRA-CellIndex, + physCellId EUTRA-PhysCellId, + cellIndividualOffset EUTRA-Q-OffsetRange +} + + +EUTRA-BlackCell ::= SEQUENCE { + cellIndexEUTRA EUTRA-CellIndex, + physCellIdRange EUTRA-PhysCellIdRange +} + +-- TAG-MEASOBJECTEUTRA-STOP +-- TAG-MEASOBJECTID-START + +MeasObjectId ::= INTEGER (1..maxNrofObjectId) + +-- TAG-MEASOBJECTID-STOP +-- TAG-MEASOBJECTNR-START + +MeasObjectNR ::= SEQUENCE { + ssbFrequency ARFCN-ValueNR OPTIONAL, -- Cond SSBorAssociatedSSB + ssbSubcarrierSpacing SubcarrierSpacing OPTIONAL, -- Cond SSBorAssociatedSSB + smtc1 SSB-MTC OPTIONAL, -- Cond SSBorAssociatedSSB + smtc2 SSB-MTC2 OPTIONAL, -- Cond IntraFreqConnected + refFreqCSI-RS ARFCN-ValueNR OPTIONAL, -- Cond CSI-RS + referenceSignalConfig ReferenceSignalConfig, + absThreshSS-BlocksConsolidation ThresholdNR OPTIONAL, -- Need R + absThreshCSI-RS-Consolidation ThresholdNR OPTIONAL, -- Need R + nrofSS-BlocksToAverage INTEGER (2..maxNrofSS-BlocksToAverage) OPTIONAL, -- Need R + nrofCSI-RS-ResourcesToAverage INTEGER (2..maxNrofCSI-RS-ResourcesToAverage) OPTIONAL, -- Need R + quantityConfigIndex INTEGER (1..maxNrofQuantityConfig), + offsetMO Q-OffsetRangeList, + cellsToRemoveList PCI-List OPTIONAL, -- Need N + cellsToAddModList CellsToAddModList OPTIONAL, -- Need N + blackCellsToRemoveList PCI-RangeIndexList OPTIONAL, -- Need N + blackCellsToAddModList SEQUENCE (SIZE (1..maxNrofPCI-Ranges)) OF PCI-RangeElement OPTIONAL, -- Need N + whiteCellsToRemoveList PCI-RangeIndexList OPTIONAL, -- Need N + whiteCellsToAddModList SEQUENCE (SIZE (1..maxNrofPCI-Ranges)) OF PCI-RangeElement OPTIONAL, -- Need N + ..., + [[ + freqBandIndicatorNR FreqBandIndicatorNR OPTIONAL, -- Need R + measCycleSCell ENUMERATED {sf160, sf256, sf320, sf512, sf640, sf1024, sf1280} OPTIONAL -- Need R + ]], + [[ + + smtc3list-r16 SSB-MTC3List-r16 OPTIONAL, -- Need R + rmtc-Config-r16 SetupRelease {RMTC-Config-r16} OPTIONAL, -- Need M + t312-r16 SetupRelease { T312-r16 } OPTIONAL -- Need M + ]] +} + +SSB-MTC3List-r16::= SEQUENCE (SIZE(1..4)) OF SSB-MTC3-r16 + +T312-r16 ::= ENUMERATED { ms0, ms50, ms100, ms200, ms300, ms400, ms500, ms1000} + +ReferenceSignalConfig::= SEQUENCE { + ssb-ConfigMobility SSB-ConfigMobility OPTIONAL, -- Need M + csi-rs-ResourceConfigMobility SetupRelease { CSI-RS-ResourceConfigMobility } OPTIONAL -- Need M +} + +SSB-ConfigMobility::= SEQUENCE { + + ssb-ToMeasure SetupRelease { SSB-ToMeasure } OPTIONAL, -- Need M + deriveSSB-IndexFromCell BOOLEAN, + ss-RSSI-Measurement SS-RSSI-Measurement OPTIONAL, -- Need M + ..., + [[ + ssb-PositionQCL-Common-r16 SSB-PositionQCL-Relation-r16 OPTIONAL, -- Cond SharedSpectrum + ssb-PositionQCL-CellsToAddModList-r16 SSB-PositionQCL-CellsToAddModList-r16 OPTIONAL, -- Need N + ssb-PositionQCL-CellsToRemoveList-r16 PCI-List OPTIONAL -- Need N + ]] + +} + + +Q-OffsetRangeList ::= SEQUENCE { + rsrpOffsetSSB Q-OffsetRange DEFAULT dB0, + rsrqOffsetSSB Q-OffsetRange DEFAULT dB0, + sinrOffsetSSB Q-OffsetRange DEFAULT dB0, + rsrpOffsetCSI-RS Q-OffsetRange DEFAULT dB0, + rsrqOffsetCSI-RS Q-OffsetRange DEFAULT dB0, + sinrOffsetCSI-RS Q-OffsetRange DEFAULT dB0 +} + + +ThresholdNR ::= SEQUENCE{ + thresholdRSRP RSRP-Range OPTIONAL, -- Need R + thresholdRSRQ RSRQ-Range OPTIONAL, -- Need R + thresholdSINR SINR-Range OPTIONAL -- Need R +} + +CellsToAddModList ::= SEQUENCE (SIZE (1..maxNrofCellMeas)) OF CellsToAddMod + +CellsToAddMod ::= SEQUENCE { + physCellId PhysCellId, + cellIndividualOffset Q-OffsetRangeList +} + +RMTC-Config-r16 ::= SEQUENCE { + rmtc-Periodicity-r16 ENUMERATED {ms40, ms80, ms160, ms320, ms640}, + rmtc-SubframeOffset-r16 INTEGER(0..639) OPTIONAL, -- Need M + measDurationSymbols-r16 ENUMERATED {sym1, sym14or12, sym28or24, sym42or36, sym70or60}, + rmtc-Frequency-r16 ARFCN-ValueNR, + ref-SCS-CP-r16 ENUMERATED {kHz15, kHz30, kHz60-NCP, kHz60-ECP}, + ... +} + +SSB-PositionQCL-CellsToAddModList-r16 ::= SEQUENCE (SIZE (1..maxNrofCellMeas)) OF SSB-PositionQCL-CellsToAddMod-r16 + +SSB-PositionQCL-CellsToAddMod-r16 ::= SEQUENCE { + physCellId-r16 PhysCellId, + ssb-PositionQCL-r16 SSB-PositionQCL-Relation-r16 +} + +-- TAG-MEASOBJECTNR-STOP +-- TAG-MEASOBJECTNR-SL-START + +MeasObjectNR-SL-r16 ::= SEQUENCE { + tx-PoolMeasToRemoveList-r16 Tx-PoolMeasList-r16 OPTIONAL, -- Need N + tx-PoolMeasToAddModList-r16 Tx-PoolMeasList-r16 OPTIONAL -- Need N +} + +Tx-PoolMeasList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-PoolToMeasureNR-r16)) OF SL-ResourcePoolID-r16 + +-- TAG-MEASOBJECTNR-SL-STOP +-- TAG-MEASOBJECTTOADDMODLIST-START + +MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxNrofObjectId)) OF MeasObjectToAddMod + +MeasObjectToAddMod ::= SEQUENCE { + measObjectId MeasObjectId, + measObject CHOICE { + measObjectNR MeasObjectNR, + ..., + measObjectEUTRA MeasObjectEUTRA, + measObjectUTRA-FDD-r16 MeasObjectUTRA-FDD-r16, + measObjectNR-SL-r16 MeasObjectNR-SL-r16, + measObjectCLI-r16 MeasObjectCLI-r16 + } +} + +-- TAG-MEASOBJECTTOADDMODLIST-STOP +-- TAG-MEASOBJECTUTRA-FDD-START + +MeasObjectUTRA-FDD-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueUTRA-FDD-r16, + utra-FDD-Q-OffsetRange-r16 UTRA-FDD-Q-OffsetRange-r16 OPTIONAL, -- Need R + cellsToRemoveList-r16 UTRA-FDD-CellIndexList-r16 OPTIONAL, -- Need N + cellsToAddModList-r16 CellsToAddModListUTRA-FDD-r16 OPTIONAL, -- Need N + ... +} + +CellsToAddModListUTRA-FDD-r16 ::= SEQUENCE (SIZE (1..maxCellMeasUTRA-FDD-r16)) OF CellsToAddModUTRA-FDD-r16 + +CellsToAddModUTRA-FDD-r16 ::= SEQUENCE { + cellIndexUTRA-FDD-r16 UTRA-FDD-CellIndex-r16, + physCellId-r16 PhysCellIdUTRA-FDD-r16 +} + +UTRA-FDD-CellIndexList-r16 ::= SEQUENCE (SIZE (1..maxCellMeasUTRA-FDD-r16)) OF UTRA-FDD-CellIndex-r16 + +UTRA-FDD-CellIndex-r16 ::= INTEGER (1..maxCellMeasUTRA-FDD-r16) + +-- TAG-MEASOBJECTUTRA-FDD-STOP +-- TAG-MEASRESULTCELLLISTSFTD-NR-START + +MeasResultCellListSFTD-NR ::= SEQUENCE (SIZE (1..maxCellSFTD)) OF MeasResultCellSFTD-NR + +MeasResultCellSFTD-NR ::= SEQUENCE { + physCellId PhysCellId, + sfn-OffsetResult INTEGER (0..1023), + frameBoundaryOffsetResult INTEGER (-30720..30719), + rsrp-Result RSRP-Range OPTIONAL +} + +-- TAG-MEASRESULTCELLLISTSFTD-NR-STOP +-- TAG-MEASRESULTCELLLISTSFTD-EUTRA-START + +MeasResultCellListSFTD-EUTRA ::= SEQUENCE (SIZE (1..maxCellSFTD)) OF MeasResultSFTD-EUTRA + +MeasResultSFTD-EUTRA ::= SEQUENCE { + eutra-PhysCellId EUTRA-PhysCellId, + sfn-OffsetResult INTEGER (0..1023), + frameBoundaryOffsetResult INTEGER (-30720..30719), + rsrp-Result RSRP-Range OPTIONAL +} + +-- TAG-MEASRESULTCELLLISTSFTD-EUTRA-STOP +-- TAG-MEASRESULTS-START + +MeasResults ::= SEQUENCE { + measId MeasId, + measResultServingMOList MeasResultServMOList, + measResultNeighCells CHOICE { + measResultListNR MeasResultListNR, + ..., + measResultListEUTRA MeasResultListEUTRA, + measResultListUTRA-FDD-r16 MeasResultListUTRA-FDD-r16 + } OPTIONAL, + ..., + [[ + measResultServFreqListEUTRA-SCG MeasResultServFreqListEUTRA-SCG OPTIONAL, + measResultServFreqListNR-SCG MeasResultServFreqListNR-SCG OPTIONAL, + measResultSFTD-EUTRA MeasResultSFTD-EUTRA OPTIONAL, + measResultSFTD-NR MeasResultCellSFTD-NR OPTIONAL + ]], + [[ + measResultCellListSFTD-NR MeasResultCellListSFTD-NR OPTIONAL + ]], + [[ + measResultForRSSI-r16 MeasResultForRSSI-r16 OPTIONAL, + locationInfo-r16 LocationInfo-r16 OPTIONAL, + ul-PDCP-DelayValueResultList-r16 UL-PDCP-DelayValueResultList-r16 OPTIONAL, + measResultsSL-r16 MeasResultsSL-r16 OPTIONAL, + measResultCLI-r16 MeasResultCLI-r16 OPTIONAL + ]] + + +} + +MeasResultServMOList ::= SEQUENCE (SIZE (1..maxNrofServingCells)) OF MeasResultServMO + +MeasResultServMO ::= SEQUENCE { + servCellId ServCellIndex, + measResultServingCell MeasResultNR, + measResultBestNeighCell MeasResultNR OPTIONAL, + ... +} + +MeasResultListNR ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultNR + +MeasResultNR ::= SEQUENCE { + physCellId PhysCellId OPTIONAL, + measResult SEQUENCE { + cellResults SEQUENCE{ + resultsSSB-Cell MeasQuantityResults OPTIONAL, + resultsCSI-RS-Cell MeasQuantityResults OPTIONAL + }, + rsIndexResults SEQUENCE{ + resultsSSB-Indexes ResultsPerSSB-IndexList OPTIONAL, + resultsCSI-RS-Indexes ResultsPerCSI-RS-IndexList OPTIONAL + } OPTIONAL + }, + ..., + [[ + cgi-Info CGI-InfoNR OPTIONAL + ]] +} + +MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA + +MeasResultEUTRA ::= SEQUENCE { + eutra-PhysCellId PhysCellId, + measResult MeasQuantityResultsEUTRA, + + cgi-Info CGI-InfoEUTRA OPTIONAL, + ... +} + +MultiBandInfoListEUTRA ::= SEQUENCE (SIZE (1..maxMultiBands)) OF FreqBandIndicatorEUTRA + +MeasQuantityResults ::= SEQUENCE { + rsrp RSRP-Range OPTIONAL, + rsrq RSRQ-Range OPTIONAL, + sinr SINR-Range OPTIONAL +} + +MeasQuantityResultsEUTRA ::= SEQUENCE { + rsrp RSRP-RangeEUTRA OPTIONAL, + rsrq RSRQ-RangeEUTRA OPTIONAL, + sinr SINR-RangeEUTRA OPTIONAL +} + +ResultsPerSSB-IndexList::= SEQUENCE (SIZE (1..maxNrofIndexesToReport2)) OF ResultsPerSSB-Index + +ResultsPerSSB-Index ::= SEQUENCE { + ssb-Index SSB-Index, + ssb-Results MeasQuantityResults OPTIONAL +} + +ResultsPerCSI-RS-IndexList::= SEQUENCE (SIZE (1..maxNrofIndexesToReport2)) OF ResultsPerCSI-RS-Index + +ResultsPerCSI-RS-Index ::= SEQUENCE { + csi-RS-Index CSI-RS-Index, + csi-RS-Results MeasQuantityResults OPTIONAL +} +MeasResultServFreqListEUTRA-SCG ::= SEQUENCE (SIZE (1..maxNrofServingCellsEUTRA)) OF MeasResult2EUTRA + +MeasResultServFreqListNR-SCG ::= SEQUENCE (SIZE (1..maxNrofServingCells)) OF MeasResult2NR + +MeasResultListUTRA-FDD-r16 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA-FDD-r16 + +MeasResultUTRA-FDD-r16 ::= SEQUENCE { + physCellId-r16 PhysCellIdUTRA-FDD-r16, + measResult-r16 SEQUENCE { + utra-FDD-RSCP-r16 INTEGER (-5..91) OPTIONAL, + utra-FDD-EcN0-r16 INTEGER (0..49) OPTIONAL + } +} + +MeasResultForRSSI-r16 ::= SEQUENCE { + rssi-Result-r16 ENUMERATED{ffs}, + channelOccupancy-r16 INTEGER (0..100) +} + +MeasResultCLI-r16 ::= SEQUENCE { + measResultListSRS-RSRP-r16 MeasResultListSRS-RSRP-r16 OPTIONAL, + measResultListCLI-RSSI-r16 MeasResultListCLI-RSSI-r16 OPTIONAL +} + +MeasResultListSRS-RSRP-r16 ::= SEQUENCE (SIZE (1.. maxCLI-Report-r16)) OF MeasResultSRS-RSRP-r16 + +MeasResultSRS-RSRP-r16 ::= SEQUENCE { + srs-ResourceId-r16 SRS-ResourceId, + srs-RSRP-Result-r16 SRS-RSRP-Range-r16 +} + +MeasResultListCLI-RSSI-r16 ::= SEQUENCE (SIZE (1.. maxCLI-Report-r16)) OF MeasResultCLI-RSSI-r16 + +MeasResultCLI-RSSI-r16 ::= SEQUENCE { + rssi-ResourceId-r16 RSSI-ResourceId-r16, + cli-RSSI-Result-r16 CLI-RSSI-Range-r16 +} + +UL-PDCP-DelayValueResultList-r16 ::= SEQUENCE (SIZE (1..maxDRB)) OF UL-PDCP-DelayValueResult-r16 + +UL-PDCP-DelayValueResult-r16 ::= SEQUENCE { + drb-Id-r16 DRB-Identity, + averageDelay-r16 INTEGER (0..10000), + ... +} + +-- TAG-MEASRESULTS-STOP +-- TAG-MEASRESULT2EUTRA-START + +MeasResult2EUTRA ::= SEQUENCE { + carrierFreq ARFCN-ValueEUTRA, + measResultServingCell MeasResultEUTRA OPTIONAL, + measResultBestNeighCell MeasResultEUTRA OPTIONAL, + ... +} + +-- TAG-MEASRESULT2EUTRA-STOP +-- TAG-MEASRESULT2NR-START + +MeasResult2NR ::= SEQUENCE { + ssbFrequency ARFCN-ValueNR OPTIONAL, + refFreqCSI-RS ARFCN-ValueNR OPTIONAL, + measResultServingCell MeasResultNR OPTIONAL, + measResultNeighCellListNR MeasResultListNR OPTIONAL, + ... +} + +-- TAG-MEASRESULT2NR-STOP +-- TAG-MEASRESULTIDLEEUTRA-START + +MeasResultIdleEUTRA-r16 ::= SEQUENCE { + measResultsPerCarrierListIdleEUTRA-r16 SEQUENCE (SIZE (1.. maxFreqIdle-r16)) OF MeasResultsPerCarrierIdleEUTRA-r16, + ... +} + +MeasResultsPerCarrierIdleEUTRA-r16 ::= SEQUENCE { + carrierFreqEUTRA-r16 ARFCN-ValueEUTRA, + measResultsPerCellListIdleEUTRA-r16 SEQUENCE (SIZE (1..maxCellMeasIdle-r16)) OF MeasResultsPerCellIdleEUTRA-r16, + ... +} + +MeasResultsPerCellIdleEUTRA-r16 ::= SEQUENCE { + eutra-PhysCellId-r16 EUTRA-PhysCellId, + measIdleResultEUTRA-r16 SEQUENCE { + rsrp-ResultEUTRA-r16 RSRP-RangeEUTRA OPTIONAL, + rsrq-ResultEUTRA-r16 RSRQ-RangeEUTRA-r16 OPTIONAL + }, + ... +} + +-- TAG-MEASRESULTIDLEEUTRA-STOP +-- TAG-MEASRESULTIDLENR-START + +MeasResultIdleNR-r16 ::= SEQUENCE { + measResultServingCell-r16 SEQUENCE { + rsrp-Result-r16 RSRP-Range OPTIONAL, + rsrq-Result-r16 RSRQ-Range OPTIONAL, + resultsSSB-Indexes-r16 ResultsPerSSB-IndexList-r16 OPTIONAL + }, + measResultsPerCarrierListIdleNR-r16 SEQUENCE (SIZE (1.. maxFreqIdle-r16)) OF MeasResultsPerCarrierIdleNR-r16 OPTIONAL, + ... +} + +MeasResultsPerCarrierIdleNR-r16 ::= SEQUENCE { + carrierFreq-r16 ARFCN-ValueNR, + measResultsPerCellListIdleNR-r16 SEQUENCE (SIZE (1..maxCellMeasIdle-r16)) OF MeasResultsPerCellIdleNR-r16, + ... +} + +MeasResultsPerCellIdleNR-r16 ::= SEQUENCE { + physCellId-r16 PhysCellId, + measIdleResultNR-r16 SEQUENCE { + rsrp-Result-r16 RSRP-Range OPTIONAL, + rsrq-Result-r16 RSRQ-Range OPTIONAL, + resultsSSB-Indexes-r16 ResultsPerSSB-IndexList-r16 OPTIONAL + }, + ... +} + +ResultsPerSSB-IndexList-r16 ::= SEQUENCE (SIZE (1.. maxNrofIndexesToReport)) OF ResultsPerSSB-IndexIdle-r16 + +ResultsPerSSB-IndexIdle-r16 ::= SEQUENCE { + ssb-Index-r16 SSB-Index, + ssb-Results-r16 SEQUENCE { + ssb-RSRP-Result-r16 RSRP-Range OPTIONAL, + ssb-RSRQ-Result-r16 RSRQ-Range OPTIONAL + } OPTIONAL +} + +-- TAG-MEASRESULTIDLENR-STOP +-- TAG-MEASRESULTSCG-FAILURE-START + +MeasResultSCG-Failure ::= SEQUENCE { + measResultPerMOList MeasResultList2NR, + ..., + [[ + locationInfo-r16 LocationInfo-r16 OPTIONAL + ]] +} + +MeasResultList2NR ::= SEQUENCE (SIZE (1..maxFreq)) OF MeasResult2NR + +-- TAG-MEASRESULTSCG-FAILURE-STOP +-- TAG-MEASRESULTSSL-START + +MeasResultsSL-r16 ::= SEQUENCE { + measResultsListSL-r16 CHOICE { + measResultNR-SL-r16 MeasResultNR-SL-r16, + ... + }, + ... +} + +MeasResultNR-SL-r16 ::= SEQUENCE { + measResultListCBR-NR-r16 SEQUENCE (SIZE (1.. maxNrofSL-PoolToMeasureNR-r16)) OF MeasResultCBR-NR-r16, + ... +} + +MeasResultCBR-NR-r16 ::= SEQUENCE { + sl-poolReportIdentity-r16 SL-ResourcePoolID-r16, + sl-CBR-ResultsNR-r16 SL-CBR-r16, + ... +} + +-- TAG-MEASRESULTSSL-STOP +-- TAG-MEASTRIGGERQUANTITYEUTRA-START + +MeasTriggerQuantityEUTRA::= CHOICE { + rsrp RSRP-RangeEUTRA, + rsrq RSRQ-RangeEUTRA, + sinr SINR-RangeEUTRA +} + +RSRP-RangeEUTRA ::= INTEGER (0..97) + +RSRQ-RangeEUTRA ::= INTEGER (0..34) + +SINR-RangeEUTRA ::= INTEGER (0..127) + +-- TAG-MEASTRIGGERQUANTITYEUTRA-STOP +-- TAG-MOBILITYSTATEPARAMETERS-START + +MobilityStateParameters ::= SEQUENCE{ + t-Evaluation ENUMERATED { + s30, s60, s120, s180, s240, spare3, spare2, spare1}, + t-HystNormal ENUMERATED { + s30, s60, s120, s180, s240, spare3, spare2, spare1}, + n-CellChangeMedium INTEGER (1..16), + n-CellChangeHigh INTEGER (1..16) +} + +-- TAG-MOBILITYSTATEPARAMETERS-STOP +-- TAG-MSGACONFIGCOMMON-START + +MsgA-ConfigCommon-r16 ::= SEQUENCE { + rach-ConfigCommonTwoStepRA-r16 RACH-ConfigCommonTwoStepRA-r16, + msgA-PUSCH-Config-r16 MsgA-PUSCH-Config-r16 OPTIONAL --Cond InitialBWPConfig +} +-- TAG-MSGACONFIGCOMMON-STOP +-- TAG-MSGA-PUSCH-CONFIG-START + +MsgA-PUSCH-Config-r16 ::= SEQUENCE { + msgA-PUSCH-ResourceGroupA-r16 MsgA-PUSCH-Resource-r16 OPTIONAL, -- Cond InitialBWPConfig + msgA-PUSCH-ResourceGroupB-r16 MsgA-PUSCH-Resource-r16 OPTIONAL, -- Cond GroupBConfigured + msgA-TransformPrecoder-r16 ENUMERATED {enabled, disabled} OPTIONAL, -- Need R + msgA-DataScramblingIndex-r16 INTEGER (0..1023) OPTIONAL, -- Need S + msgA-DeltaPreamble-r16 INTEGER (-1..6) OPTIONAL -- Need R +} + +MsgA-PUSCH-Resource-r16 ::= SEQUENCE { + msgA-MCS-r16 INTEGER (0..15), + nrofSlotsMsgA-PUSCH-r16 INTEGER (1..4), + nrofMsgA-PO-PerSlot-r16 ENUMERATED {one, two, three, six}, + msgA-PUSCH-TimeDomainOffset-r16 INTEGER (1..32), + msgA-PUSCH-TimeDomainAllocation-r16 INTEGER (1..maxNrofUL-Allocations) OPTIONAL, -- Need S + startSymbolAndLengthMsgA-PO-r16 INTEGER (0..127) OPTIONAL, -- Need S + mappingTypeMsgA-PUSCH-r16 ENUMERATED {typeA, typeB} OPTIONAL, -- Need S + guardPeriodMsgA-PUSCH-r16 INTEGER (0..3) OPTIONAL, -- Need R + guardBandMsgA-PUSCH-r16 INTEGER (0..1), + frequencyStartMsgA-PUSCH-r16 INTEGER (0..maxNrofPhysicalResourceBlocks-1), + nrofPRBs-PerMsgA-PO-r16 INTEGER (1..32), + nrofMsgA-PO-FDM-r16 ENUMERATED {one, two, four, eight}, + msgA-IntraSlotFrequencyHopping-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + msgA-HoppingBits-r16 BIT STRING (SIZE(2)) OPTIONAL, -- Need R + msgA-DMRS-Config-r16 MsgA-DMRS-Config-r16, + nrofDMRS-Sequences-r16 INTEGER (1..2), + msgA-Alpha-r16 ENUMERATED {alpha0, alpha04, alpha05, alpha06, + alpha07, alpha08, alpha09, alpha1} OPTIONAL, -- Need S + interlaceIndexFirstPO-MsgA-PUSCH-r16 INTEGER (1..10) OPTIONAL, -- Need R + nrofInterlacesPerMsgA-PO-r16 INTEGER (1..10) OPTIONAL, -- Need R + ... +} + +MsgA-DMRS-Config-r16 ::= SEQUENCE { + msgA-DMRS-AdditionalPosition-r16 ENUMERATED {pos0, pos1, pos3} OPTIONAL, -- Need S + msgA-MaxLength-r16 ENUMERATED {len2} OPTIONAL, -- Need S + msgA-PUSCH-DMRS-CDM-Group-r16 INTEGER (0..1) OPTIONAL, -- Need S + msgA-PUSCH-NrofPorts-r16 INTEGER (0..1) OPTIONAL, -- Need S + msgA-ScramblingID0-r16 INTEGER (0..65536) OPTIONAL, -- Need S + msgA-ScramblingID1-r16 INTEGER (0..65536) OPTIONAL -- Need S +} + +-- TAG-MSGA-PUSCH-CONFIG-STOP +-- TAG-MULTIFREQUENCYBANDLISTNR-START + +MultiFrequencyBandListNR ::= SEQUENCE (SIZE (1..maxNrofMultiBands)) OF FreqBandIndicatorNR + +-- TAG-MULTIFREQUENCYBANDLISTNR-STOP +-- TAG-MULTIFREQUENCYBANDLISTNR-SIB-START + +MultiFrequencyBandListNR-SIB ::= SEQUENCE (SIZE (1.. maxNrofMultiBands)) OF NR-MultiBandInfo + +NR-MultiBandInfo ::= SEQUENCE { + freqBandIndicatorNR FreqBandIndicatorNR OPTIONAL, -- Cond OptULNotSIB2 + nr-NS-PmaxList NR-NS-PmaxList OPTIONAL -- Need S +} + +-- TAG-MULTIFREQUENCYBANDLISTNR-SIB-STOP +-- TAG-NeedForGapsConfigNR-START + +NeedForGapsConfigNR-r16 ::= SEQUENCE { + requestedTargetBandFilterNR-r16 SEQUENCE (SIZE (1..maxBands)) OF FreqBandIndicatorNR OPTIONAL -- Need R +} + +-- TAG-NeedForGapsConfigNR-STOP +-- TAG-NeedForGapsInfoNR-START + +NeedForGapsInfoNR-r16 ::= SEQUENCE { + intraFreq-needForGap-r16 NeedForGapsIntraFreqlist-r16, + interFreq-needForGap-r16 NeedForGapsBandlistNR-r16 +} + +NeedForGapsIntraFreqlist-r16 ::= SEQUENCE (SIZE (1.. maxNrofServingCells)) OF NeedForGapsIntraFreq-r16 + +NeedForGapsBandlistNR-r16 ::= SEQUENCE (SIZE (1..maxBands)) OF NeedForGapsNR-r16 + +NeedForGapsIntraFreq-r16 ::= SEQUENCE { + servCellId-r16 ServCellIndex, + gapIndicationIntra-r16 ENUMERATED {gap, no-gap} +} + +NeedForGapsNR-r16 ::= SEQUENCE { + bandNR-r16 FreqBandIndicatorNR, + gapIndication-r16 ENUMERATED {gap, no-gap} +} + +-- TAG-NeedForGapsInfoNR-STOP +-- TAG-NEXTHOPCHAININGCOUNT-START + +NextHopChainingCount ::= INTEGER (0..7) + +-- TAG-NEXTHOPCHAININGCOUNT-STOP +-- TAG-NG-5G-S-TMSI-START + +NG-5G-S-TMSI ::= BIT STRING (SIZE (48)) + +-- TAG-NG-5G-S-TMSI-STOP +-- TAG-NPN-IDENTITY-START + +NPN-Identity-r16 ::= CHOICE { + pni-npn-r16 SEQUENCE { + plmn-Identity-r16 PLMN-Identity, + cag-IdentityList-r16 SEQUENCE (SIZE (1..maxNPN-r16)) OF CAG-IdentityInfo-r16 + }, + snpn-r16 SEQUENCE { + plmn-Identity PLMN-Identity, + nid-List-r16 SEQUENCE (SIZE (1..maxNPN-r16)) OF NID-r16 + } +} + +CAG-IdentityInfo-r16 ::= SEQUENCE { + cag-Identity-r16 BIT STRING (SIZE (32)), + manualCAGselectionAllowed-r16 ENUMERATED {true} OPTIONAL -- Need R +} + +NID-r16 ::= BIT STRING (SIZE (44)) + +-- TAG-NPN-IDENTITY-STOP +-- TAG-NPN-IDENTITYINFOLIST-START + +NPN-IdentityInfoList-r16 ::= SEQUENCE (SIZE (1..maxNPN-r16)) OF NPN-IdentityInfo-r16 + + +NPN-IdentityInfo-r16 ::= SEQUENCE { + npn-IdentityList-r16 SEQUENCE (SIZE (1..maxNPN-r16)) OF NPN-Identity-r16, + trackingAreaCode-r16 TrackingAreaCode, + ranac-r16 RAN-AreaCode OPTIONAL, -- Need R + cellIdentity-r16 CellIdentity, + cellReservedForOperatorUse-r16 ENUMERATED {reserved, notReserved}, + iab-Support-r16 ENUMERATED {true} OPTIONAL, -- Need R + ... +} + +-- TAG-NPN-IDENTITYINFOLIST-STOP +-- TAG-NR-NS-PMAXLIST-START + +NR-NS-PmaxList ::= SEQUENCE (SIZE (1..maxNR-NS-Pmax)) OF NR-NS-PmaxValue + +NR-NS-PmaxValue ::= SEQUENCE { + additionalPmax P-Max OPTIONAL, -- Need N + additionalSpectrumEmission AdditionalSpectrumEmission +} + +-- TAG-NR-NS-PMAXLIST-STOP +-- TAG-NZP-CSI-RS-RESOURCE-START + +NZP-CSI-RS-Resource ::= SEQUENCE { + nzp-CSI-RS-ResourceId NZP-CSI-RS-ResourceId, + resourceMapping CSI-RS-ResourceMapping, + powerControlOffset INTEGER (-8..15), + powerControlOffsetSS ENUMERATED{db-3, db0, db3, db6} OPTIONAL, -- Need R + scramblingID ScramblingId, + periodicityAndOffset CSI-ResourcePeriodicityAndOffset OPTIONAL, -- Cond PeriodicOrSemiPersistent + qcl-InfoPeriodicCSI-RS TCI-StateId OPTIONAL, -- Cond Periodic + ... +} + +-- TAG-NZP-CSI-RS-RESOURCE-STOP +-- TAG-NZP-CSI-RS-RESOURCEID-START + +NZP-CSI-RS-ResourceId ::= INTEGER (0..maxNrofNZP-CSI-RS-Resources-1) + +-- TAG-NZP-CSI-RS-RESOURCEID-STOP +-- TAG-NZP-CSI-RS-RESOURCESET-START +NZP-CSI-RS-ResourceSet ::= SEQUENCE { + nzp-CSI-ResourceSetId NZP-CSI-RS-ResourceSetId, + nzp-CSI-RS-Resources SEQUENCE (SIZE (1..maxNrofNZP-CSI-RS-ResourcesPerSet)) OF NZP-CSI-RS-ResourceId, + repetition ENUMERATED { on, off } OPTIONAL, -- Need S + aperiodicTriggeringOffset INTEGER(0..6) OPTIONAL, -- Need S + trs-Info ENUMERATED {true} OPTIONAL, -- Need R + ..., + [[ + aperiodicTriggeringOffset-r16 INTEGER(0..31) OPTIONAL -- Need S + ]] +} + +-- TAG-NZP-CSI-RS-RESOURCESET-STOP +-- TAG-NZP-CSI-RS-RESOURCESETID-START + +NZP-CSI-RS-ResourceSetId ::= INTEGER (0..maxNrofNZP-CSI-RS-ResourceSets-1) + +-- TAG-NZP-CSI-RS-RESOURCESETID-STOP +-- TAG-P-MAX-START + +P-Max ::= INTEGER (-30..33) + +-- TAG-P-MAX-STOP +-- TAG-PCI-LIST-START + +PCI-List ::= SEQUENCE (SIZE (1..maxNrofCellMeas)) OF PhysCellId + +-- TAG-PCI-LIST-STOP +-- TAG-PCI-RANGE-START + +PCI-Range ::= SEQUENCE { + start PhysCellId, + range ENUMERATED {n4, n8, n12, n16, n24, n32, n48, n64, n84, + n96, n128, n168, n252, n504, n1008,spare1} OPTIONAL -- Need S +} + +-- TAG-PCI-RANGE-STOP +-- TAG-PCI-RANGEELEMENT-START + +PCI-RangeElement ::= SEQUENCE { + pci-RangeIndex PCI-RangeIndex, + pci-Range PCI-Range +} + +-- TAG-PCI-RANGEELEMENT-STOP +-- TAG-PCI-RANGEINDEX-START + +PCI-RangeIndex ::= INTEGER (1..maxNrofPCI-Ranges) + +-- TAG-PCI-RANGEINDEX-STOP +-- TAG-PCI-RANGEINDEXLIST-START + +PCI-RangeIndexList ::= SEQUENCE (SIZE (1..maxNrofPCI-Ranges)) OF PCI-RangeIndex + +-- TAG-PCI-RANGEINDEXLIST-STOP +-- TAG-PDCCH-CONFIG-START + +PDCCH-Config ::= SEQUENCE { + controlResourceSetToAddModList SEQUENCE(SIZE (1..3)) OF ControlResourceSet OPTIONAL, -- Need N + controlResourceSetToReleaseList SEQUENCE(SIZE (1..3)) OF ControlResourceSetId OPTIONAL, -- Need N + searchSpacesToAddModList SEQUENCE(SIZE (1..10)) OF SearchSpace OPTIONAL, -- Need N + searchSpacesToReleaseList SEQUENCE(SIZE (1..10)) OF SearchSpaceId OPTIONAL, -- Need N + downlinkPreemption SetupRelease { DownlinkPreemption } OPTIONAL, -- Need M + tpc-PUSCH SetupRelease { PUSCH-TPC-CommandConfig } OPTIONAL, -- Need M + tpc-PUCCH SetupRelease { PUCCH-TPC-CommandConfig } OPTIONAL, -- Need M + tpc-SRS SetupRelease { SRS-TPC-CommandConfig} OPTIONAL, -- Need M + ..., + [[ + controlResourceSetToAddModList2-r16 SEQUENCE (SIZE (1..2)) OF ControlResourceSet OPTIONAL, -- Need N + controlResourceSetToReleaseList-r16 SEQUENCE (SIZE (1..5)) OF ControlResourceSetId-r16 OPTIONAL, -- Need N + searchSpacesToAddModListExt-r16 SEQUENCE(SIZE (1..10)) OF SearchSpaceExt-r16 OPTIONAL, -- Need N + searchSpaceSwitchingTimer-r16 INTEGER (1..80) OPTIONAL, -- Need R + cellGroupsForSwitchingList-r16 SEQUENCE(SIZE (1..4)) OF CellGroupForSwitching-r16 OPTIONAL, -- Need R + uplinkCancellation-r16 SetupRelease { UplinkCancellation-r16 } OPTIONAL, -- Need M + monitoringCapabilityConfig-r16 ENUMERATED { r15monitoringcapability,r16monitoringcapability } OPTIONAL, -- Need M + searchSpaceSwitchingDelay-r16 INTEGER (10..52) OPTIONAL -- Need R + ]] +} + +CellGroupForSwitching-r16 ::= SEQUENCE(SIZE (1..16)) OF ServCellIndex + +-- TAG-PDCCH-CONFIG-STOP +-- TAG-PDCCH-CONFIGCOMMON-START + +PDCCH-ConfigCommon ::= SEQUENCE { + controlResourceSetZero ControlResourceSetZero OPTIONAL, -- Cond InitialBWP-Only + commonControlResourceSet ControlResourceSet OPTIONAL, -- Need R + searchSpaceZero SearchSpaceZero OPTIONAL, -- Cond InitialBWP-Only + commonSearchSpaceList SEQUENCE (SIZE(1..4)) OF SearchSpace OPTIONAL, -- Need R + searchSpaceSIB1 SearchSpaceId OPTIONAL, -- Need S + searchSpaceOtherSystemInformation SearchSpaceId OPTIONAL, -- Need S + pagingSearchSpace SearchSpaceId OPTIONAL, -- Need S + ra-SearchSpace SearchSpaceId OPTIONAL, -- Need S + ..., + [[ + firstPDCCH-MonitoringOccasionOfPO CHOICE { + sCS15KHZoneT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..139), + sCS30KHZoneT-SCS15KHZhalfT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..279), + sCS60KHZoneT-SCS30KHZhalfT-SCS15KHZquarterT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..559), + sCS120KHZoneT-SCS60KHZhalfT-SCS30KHZquarterT-SCS15KHZoneEighthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..1119), + sCS120KHZhalfT-SCS60KHZquarterT-SCS30KHZoneEighthT-SCS15KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..2239), + sCS120KHZquarterT-SCS60KHZoneEighthT-SCS30KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..4479), + sCS120KHZoneEighthT-SCS60KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..8959), + sCS120KHZoneSixteenthT SEQUENCE (SIZE (1..maxPO-perPF)) OF INTEGER (0..17919) + } OPTIONAL, -- Cond OtherBWP + commonSearchSpaceListExt-r16 SEQUENCE (SIZE(1..4)) OF SearchSpaceExt-r16 OPTIONAL -- Need R + ]] +} + +-- TAG-PDCCH-CONFIGCOMMON-STOP +-- TAG-PDCCH-CONFIGSIB1-START + +PDCCH-ConfigSIB1 ::= SEQUENCE { + controlResourceSetZero ControlResourceSetZero, + searchSpaceZero SearchSpaceZero +} + +-- TAG-PDCCH-CONFIGSIB1-STOP +-- TAG-PDCCH-SERVINGCELLCONFIG-START + +PDCCH-ServingCellConfig ::= SEQUENCE { + slotFormatIndicator SetupRelease { SlotFormatIndicator } OPTIONAL, -- Need M + ..., + [[ + availabilityIndicator-r16 SetupRelease {AvailabilityIndicator-r16} OPTIONAL, -- Need M + searchSpaceSwitchingTimer-r16 INTEGER (1..80) OPTIONAL -- Need R + ]] +} + +-- TAG-PDCCH-SERVINGCELLCONFIG-STOP +-- TAG-PDCP-CONFIG-START + +PDCP-Config ::= SEQUENCE { + drb SEQUENCE { + discardTimer ENUMERATED {ms10, ms20, ms30, ms40, ms50, ms60, ms75, ms100, ms150, ms200, + ms250, ms300, ms500, ms750, ms1500, infinity} OPTIONAL, -- Cond Setup + pdcp-SN-SizeUL ENUMERATED {len12bits, len18bits} OPTIONAL, -- Cond Setup2 + pdcp-SN-SizeDL ENUMERATED {len12bits, len18bits} OPTIONAL, -- Cond Setup2 + headerCompression CHOICE { + notUsed NULL, + rohc SEQUENCE { + maxCID INTEGER (1..16383) DEFAULT 15, + profiles SEQUENCE { + profile0x0001 BOOLEAN, + profile0x0002 BOOLEAN, + profile0x0003 BOOLEAN, + profile0x0004 BOOLEAN, + profile0x0006 BOOLEAN, + profile0x0101 BOOLEAN, + profile0x0102 BOOLEAN, + profile0x0103 BOOLEAN, + profile0x0104 BOOLEAN + }, + drb-ContinueROHC ENUMERATED { true } OPTIONAL -- Need N + }, + uplinkOnlyROHC SEQUENCE { + maxCID INTEGER (1..16383) DEFAULT 15, + profiles SEQUENCE { + profile0x0006 BOOLEAN + }, + drb-ContinueROHC ENUMERATED { true } OPTIONAL -- Need N + }, + ... + }, + integrityProtection ENUMERATED { enabled } OPTIONAL, -- Cond ConnectedTo5GC1 + statusReportRequired ENUMERATED { true } OPTIONAL, -- Cond Rlc-AM-UM + outOfOrderDelivery ENUMERATED { true } OPTIONAL -- Need R + } OPTIONAL, -- Cond DRB + moreThanOneRLC SEQUENCE { + primaryPath SEQUENCE { + cellGroup CellGroupId OPTIONAL, -- Need R + logicalChannel LogicalChannelIdentity OPTIONAL -- Need R + }, + ul-DataSplitThreshold UL-DataSplitThreshold OPTIONAL, -- Cond SplitBearer + pdcp-Duplication BOOLEAN OPTIONAL -- Need R + } OPTIONAL, -- Cond MoreThanOneRLC + + t-Reordering ENUMERATED { + ms0, ms1, ms2, ms4, ms5, ms8, ms10, ms15, ms20, ms30, ms40, + ms50, ms60, ms80, ms100, ms120, ms140, ms160, ms180, ms200, ms220, + ms240, ms260, ms280, ms300, ms500, ms750, ms1000, ms1250, + ms1500, ms1750, ms2000, ms2250, ms2500, ms2750, + ms3000, spare28, spare27, spare26, spare25, spare24, + spare23, spare22, spare21, spare20, + spare19, spare18, spare17, spare16, spare15, spare14, + spare13, spare12, spare11, spare10, spare09, + spare08, spare07, spare06, spare05, spare04, spare03, + spare02, spare01 } OPTIONAL, -- Need S + ..., + [[ + cipheringDisabled ENUMERATED {true} OPTIONAL -- Cond ConnectedTo5GC + ]], + [[ + discardTimerExt-r16 SetupRelease { DiscardTimerExt-r16 } OPTIONAL, -- Cond DRB2 + moreThanTwoRLC-DRB-r16 SEQUENCE { + splitSecondaryPath LogicalChannelIdentity OPTIONAL, -- Cond SplitBearer2 + duplicationState SEQUENCE (SIZE (3)) OF BOOLEAN OPTIONAL -- Need S + } OPTIONAL, -- Cond MoreThanTwoRLC-DRB + ethernetHeaderCompression-r16 SetupRelease { EthernetHeaderCompression-r16 } OPTIONAL -- Need M + ]] +} + +EthernetHeaderCompression-r16 ::= SEQUENCE { + ehc-Common SEQUENCE { + ehc-CID-Length ENUMERATED { bits7, bits15 }, + ... + }, + ehc-Downlink SEQUENCE { + drb-ContinueEHC-DL ENUMERATED { true } OPTIONAL, -- Need R + ... + } OPTIONAL, -- Need M + ehc-Uplink SEQUENCE { + maxCID-EHC-UL INTEGER (1..32767), + drb-ContinueEHC-UL ENUMERATED { true } OPTIONAL, -- Need R + ... + } OPTIONAL -- Need M +} + +UL-DataSplitThreshold ::= ENUMERATED { + b0, b100, b200, b400, b800, b1600, b3200, b6400, b12800, b25600, b51200, b102400, b204800, + b409600, b819200, b1228800, b1638400, b2457600, b3276800, b4096000, b4915200, b5734400, + b6553600, infinity, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1} + +DiscardTimerExt-r16 ::= ENUMERATED {ms0dot5, ms1, ms2, ms4, ms6, ms8, spare2, spare1} + +-- TAG-PDCP-CONFIG-STOP +-- TAG-PDSCH-CONFIG-START + +PDSCH-Config ::= SEQUENCE { + dataScramblingIdentityPDSCH INTEGER (0..1023) OPTIONAL, -- Need S + dmrs-DownlinkForPDSCH-MappingTypeA SetupRelease { DMRS-DownlinkConfig } OPTIONAL, -- Need M + dmrs-DownlinkForPDSCH-MappingTypeB SetupRelease { DMRS-DownlinkConfig } OPTIONAL, -- Need M + + tci-StatesToAddModList SEQUENCE (SIZE(1..maxNrofTCI-States)) OF TCI-State OPTIONAL, -- Need N + tci-StatesToReleaseList SEQUENCE (SIZE(1..maxNrofTCI-States)) OF TCI-StateId OPTIONAL, -- Need N + vrb-ToPRB-Interleaver ENUMERATED {n2, n4} OPTIONAL, -- Need S + resourceAllocation ENUMERATED { resourceAllocationType0, resourceAllocationType1, dynamicSwitch}, + pdsch-TimeDomainAllocationList SetupRelease { PDSCH-TimeDomainResourceAllocationList } OPTIONAL, -- Need M + pdsch-AggregationFactor ENUMERATED { n2, n4, n8 } OPTIONAL, -- Need S + rateMatchPatternToAddModList SEQUENCE (SIZE (1..maxNrofRateMatchPatterns)) OF RateMatchPattern OPTIONAL, -- Need N + rateMatchPatternToReleaseList SEQUENCE (SIZE (1..maxNrofRateMatchPatterns)) OF RateMatchPatternId OPTIONAL, -- Need N + rateMatchPatternGroup1 RateMatchPatternGroup OPTIONAL, -- Need R + rateMatchPatternGroup2 RateMatchPatternGroup OPTIONAL, -- Need R + + rbg-Size ENUMERATED {config1, config2}, + mcs-Table ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + maxNrofCodeWordsScheduledByDCI ENUMERATED {n1, n2} OPTIONAL, -- Need R + + prb-BundlingType CHOICE { + staticBundling SEQUENCE { + bundleSize ENUMERATED { n4, wideband } OPTIONAL -- Need S + }, + dynamicBundling SEQUENCE { + bundleSizeSet1 ENUMERATED { n4, wideband, n2-wideband, n4-wideband } OPTIONAL, -- Need S + bundleSizeSet2 ENUMERATED { n4, wideband } OPTIONAL -- Need S + } + }, + zp-CSI-RS-ResourceToAddModList SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-Resources)) OF ZP-CSI-RS-Resource + OPTIONAL, -- Need N + zp-CSI-RS-ResourceToReleaseList SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-Resources)) OF ZP-CSI-RS-ResourceId + OPTIONAL, -- Need N + aperiodic-ZP-CSI-RS-ResourceSetsToAddModList SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-ResourceSets)) OF ZP-CSI-RS-ResourceSet + OPTIONAL, -- Need N + aperiodic-ZP-CSI-RS-ResourceSetsToReleaseList SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-ResourceSets)) OF ZP-CSI-RS-ResourceSetId + OPTIONAL, -- Need N + sp-ZP-CSI-RS-ResourceSetsToAddModList SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-ResourceSets)) OF ZP-CSI-RS-ResourceSet + OPTIONAL, -- Need N + sp-ZP-CSI-RS-ResourceSetsToReleaseList SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-ResourceSets)) OF ZP-CSI-RS-ResourceSetId + OPTIONAL, -- Need N + p-ZP-CSI-RS-ResourceSet SetupRelease { ZP-CSI-RS-ResourceSet } + OPTIONAL, -- Need M + ..., + [[ + maxMIMO-Layers-r16 SetupRelease { MaxMIMO-LayersDL-r16 } OPTIONAL, -- Need M + minimumSchedulingOffsetK0-r16 SetupRelease { MinSchedulingOffsetK0-Values-r16 } OPTIONAL, -- Need M + + -- Start of the parameters for DCI format 1_2 introduced in V16.1.0 + antennaPortsFieldPresenceForDCI-Format1-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + aperiodicZP-CSI-RS-ResourceSetsToAddModListForDCI-Format1-2-r16 SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-ResourceSets)) OF ZP-CSI-RS-ResourceSet + OPTIONAL, -- Need N + aperiodicZP-CSI-RS-ResourceSetsToReleaseListForDCI-Format1-2-r16 SEQUENCE (SIZE (1..maxNrofZP-CSI-RS-ResourceSets)) OF ZP-CSI-RS-ResourceSetId + OPTIONAL, -- Need N + dmrs-DownlinkForPDSCH-MappingTypeA-ForDCI-Format1-2-r16 SetupRelease { DMRS-DownlinkConfig } OPTIONAL, -- Need M + dmrs-DownlinkForPDSCH-MappingTypeB-ForDCI-Format1-2-r16 SetupRelease { DMRS-DownlinkConfig } OPTIONAL, -- Need M + dmrs-SequenceInitializationForDCI-Format1-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + harq-ProcessNumberSizeForDCI-Format1-2-r16 INTEGER (0..4) OPTIONAL, -- Need R + mcs-TableForDCI-Format1-2-r16 ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + numberOfBitsForRV-ForDCI-Format1-2-r16 INTEGER (0..2) OPTIONAL, -- Need R + pdsch-TimeDomainAllocationListForDCI-Format1-2-r16 SetupRelease { PDSCH-TimeDomainResourceAllocationList-r16 } + OPTIONAL, -- Need M + prb-BundlingTypeForDCI-Format1-2-r16 CHOICE { + staticBundling-r16 SEQUENCE { + bundleSize-r16 ENUMERATED { n4, wideband } OPTIONAL -- Need S + }, + dynamicBundling-r16 SEQUENCE { + bundleSizeSet1-r16 ENUMERATED { n4, wideband, n2-wideband, n4-wideband } OPTIONAL, -- Need S + bundleSizeSet2-r16 ENUMERATED { n4, wideband } OPTIONAL -- Need S + } + } OPTIONAL, -- Need R + priorityIndicatorForDCI-Format1-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + rateMatchPatternGroup1ForDCI-Format1-2-r16 RateMatchPatternGroup OPTIONAL, -- Need R + rateMatchPatternGroup2ForDCI-Format1-2-r16 RateMatchPatternGroup OPTIONAL, -- Need R + resourceAllocationType1GranularityForDCI-Format1-2-r16 ENUMERATED {n2,n4,n8,n16} OPTIONAL, -- Need S + vrb-ToPRB-InterleaverForDCI-Format1-2-r16 ENUMERATED {n2, n4} OPTIONAL, -- Need S + referenceOfSLIVForDCI-Format1-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + resourceAllocationForDCI-Format1-2-r16 ENUMERATED { resourceAllocationType0, resourceAllocationType1, dynamicSwitch} + OPTIONAL, -- Need M + -- End of the parameters for DCI format 1_2 introduced in V16.1.0 + + priorityIndicatorForDCI-Format1-1-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + dataScramblingIdentityPDSCH2-r16 INTEGER (0..1023) OPTIONAL, -- Need R + pdsch-TimeDomainAllocationList-r16 SetupRelease { PDSCH-TimeDomainResourceAllocationList-r16 } OPTIONAL, -- Need M + repetitionSchemeConfig-r16 SetupRelease { RepetitionSchemeConfig-r16} OPTIONAL -- Need M + ]] +} + +RateMatchPatternGroup ::= SEQUENCE (SIZE (1..maxNrofRateMatchPatternsPerGroup)) OF CHOICE { + cellLevel RateMatchPatternId, + bwpLevel RateMatchPatternId +} + +MinSchedulingOffsetK0-Values-r16 ::= SEQUENCE (SIZE (1..maxNrOfMinSchedulingOffsetValues-r16)) OF INTEGER (0..maxK0-SchedulingOffset-r16) + +MaxMIMO-LayersDL-r16 ::= INTEGER (1..8) + +-- TAG-PDSCH-CONFIG-STOP +-- TAG-PDSCH-CONFIGCOMMON-START + +PDSCH-ConfigCommon ::= SEQUENCE { + pdsch-TimeDomainAllocationList PDSCH-TimeDomainResourceAllocationList OPTIONAL, -- Need R + ... +} + +-- TAG-PDSCH-CONFIGCOMMON-STOP +-- TAG-PDSCH-SERVINGCELLCONFIG-START + +PDSCH-ServingCellConfig ::= SEQUENCE { + codeBlockGroupTransmission SetupRelease { PDSCH-CodeBlockGroupTransmission } OPTIONAL, -- Need M + xOverhead ENUMERATED { xOh6, xOh12, xOh18 } OPTIONAL, -- Need S + nrofHARQ-ProcessesForPDSCH ENUMERATED {n2, n4, n6, n10, n12, n16} OPTIONAL, -- Need S + pucch-Cell ServCellIndex OPTIONAL, -- Cond SCellAddOnly + ..., + [[ + maxMIMO-Layers INTEGER (1..8) OPTIONAL, -- Need M + processingType2Enabled BOOLEAN OPTIONAL -- Need M + ]], + [[ + pdsch-CodeBlockGroupTransmissionList-r16 SetupRelease { PDSCH-CodeBlockGroupTransmissionList-r16 } OPTIONAL -- Need M + ]] +} + +PDSCH-CodeBlockGroupTransmission ::= SEQUENCE { + maxCodeBlockGroupsPerTransportBlock ENUMERATED {n2, n4, n6, n8}, + codeBlockGroupFlushIndicator BOOLEAN, + ... +} + +PDSCH-CodeBlockGroupTransmissionList-r16 ::= SEQUENCE (SIZE (1..2)) OF PDSCH-CodeBlockGroupTransmission + +-- TAG-PDSCH-SERVINGCELLCONFIG-STOP +-- TAG-PDSCH-TIMEDOMAINRESOURCEALLOCATIONLIST-START + + +PDSCH-TimeDomainResourceAllocationList ::= SEQUENCE (SIZE(1..maxNrofDL-Allocations)) OF PDSCH-TimeDomainResourceAllocation + +PDSCH-TimeDomainResourceAllocation ::= SEQUENCE { + k0 INTEGER(0..32) OPTIONAL, -- Need S + mappingType ENUMERATED {typeA, typeB}, + startSymbolAndLength INTEGER (0..127) +} + +PDSCH-TimeDomainResourceAllocationList-r16 ::= SEQUENCE (SIZE(1..maxNrofDL-Allocations)) OF PDSCH-TimeDomainResourceAllocation-r16 + +PDSCH-TimeDomainResourceAllocation-r16 ::= SEQUENCE { + k0-r16 INTEGER(0..32) OPTIONAL, -- Need S + mappingType-r16 ENUMERATED {typeA, typeB}, + startSymbolAndLength-r16 INTEGER (0..127), + repetitionNumber-r16 ENUMERATED {n2, n3, n4, n5, n6, n7, n8, n16} OPTIONAL, -- Cond Formats1-0and1-1 + ... +} + +-- TAG-PDSCH-TIMEDOMAINRESOURCEALLOCATIONLIST-STOP +-- TAG-PHR-CONFIG-START + +PHR-Config ::= SEQUENCE { + phr-PeriodicTimer ENUMERATED {sf10, sf20, sf50, sf100, sf200,sf500, sf1000, infinity}, + phr-ProhibitTimer ENUMERATED {sf0, sf10, sf20, sf50, sf100,sf200, sf500, sf1000}, + phr-Tx-PowerFactorChange ENUMERATED {dB1, dB3, dB6, infinity}, + multiplePHR BOOLEAN, + dummy BOOLEAN, + phr-Type2OtherCell BOOLEAN, + phr-ModeOtherCG ENUMERATED {real, virtual}, + ... +} + +-- TAG-PHR-CONFIG-STOP +-- TAG-PHYSCELLID-START + +PhysCellId ::= INTEGER (0..1007) + +-- TAG-PHYSCELLID-STOP +-- TAG-PHYSICALCELLGROUPCONFIG-START + +PhysicalCellGroupConfig ::= SEQUENCE { + harq-ACK-SpatialBundlingPUCCH ENUMERATED {true} OPTIONAL, -- Need S + harq-ACK-SpatialBundlingPUSCH ENUMERATED {true} OPTIONAL, -- Need S + p-NR-FR1 P-Max OPTIONAL, -- Need R + pdsch-HARQ-ACK-Codebook ENUMERATED {semiStatic, dynamic}, + tpc-SRS-RNTI RNTI-Value OPTIONAL, -- Need R + tpc-PUCCH-RNTI RNTI-Value OPTIONAL, -- Need R + tpc-PUSCH-RNTI RNTI-Value OPTIONAL, -- Need R + sp-CSI-RNTI RNTI-Value OPTIONAL, -- Need R + cs-RNTI SetupRelease { RNTI-Value } OPTIONAL, -- Need M + ..., + [[ + mcs-C-RNTI RNTI-Value OPTIONAL, -- Need R + p-UE-FR1 P-Max OPTIONAL -- Cond MCG-Only + ]], + [[ + xScale ENUMERATED {dB0, dB6, spare2, spare1} OPTIONAL -- Cond SCG-Only + ]], + [[ + pdcch-BlindDetection SetupRelease { PDCCH-BlindDetection } OPTIONAL -- Need M + ]], + [[ + dcp-Config-r16 SetupRelease { DCP-Config-r16 } OPTIONAL, -- Need M + harq-ACK-SpatialBundlingPUCCH-secondaryPUCCH-group-r16 ENUMERATED {true} OPTIONAL, -- Cond twoPUCCHgroup + harq-ACK-SpatialBundlingPUSCH-secondaryPUCCH-group-r16 ENUMERATED {true} OPTIONAL, -- Cond twoPUCCHgroup + pdsch-HARQ-ACK-Codebook-secondaryPUCCH-group-r16 ENUMERATED {semiStatic, dynamic} OPTIONAL, -- Cond twoPUCCHgroup + p-NR-FR2-r16 P-Max OPTIONAL, -- Need R + p-UE-FR2-r16 P-Max OPTIONAL, -- Cond MCG-Only + nrdc-PCmode-FR1-r16 ENUMERATED {semi-static-mode1, semi-static-mode2, dynamic} OPTIONAL, -- Cond MCG-Only + nrdc-PCmode-FR2-r16 ENUMERATED {semi-static-mode1, semi-static-mode2, dynamic} OPTIONAL, -- Cond MCG-Only + pdsch-HARQ-ACK-Codebook-r16 ENUMERATED {enhancedDynamic} OPTIONAL, -- Need R + nfi-TotalDAI-Included-r16 ENUMERATED {true} OPTIONAL, -- Need M + ul-TotalDAI-Included-r16 ENUMERATED {true} OPTIONAL, -- Need R + pdsch-HARQ-ACK-OneShotFeedback-r16 ENUMERATED {true} OPTIONAL, -- Need R + pdsch-HARQ-ACK-OneShotFeedbackNDI-r16 ENUMERATED {true} OPTIONAL, -- Need R + pdsch-HARQ-ACK-OneShotFeedbackCBG-r16 ENUMERATED {true} OPTIONAL, -- Need R + downlinkAssignmentIndexForDCI-Format0-2-r16 ENUMERATED { enabled } OPTIONAL, -- Need S + downlinkAssignmentIndexForDCI-Format1-2-r16 ENUMERATED {n1, n2, n4} OPTIONAL, -- Need S + pdsch-HARQ-ACK-CodebookList-r16 SetupRelease {PDSCH-HARQ-ACK-CodebookList-r16} OPTIONAL, -- Need M + ackNackFeedbackMode-r16 ENUMERATED {joint, separate} OPTIONAL, -- Need R + pdcch-BlindDetectionCA-CombIndicator-r16 SetupRelease { PDCCH-BlindDetectionCA-CombIndicator-r16 } OPTIONAL, -- Need M + pdcch-BlindDetection2-r16 SetupRelease { PDCCH-BlindDetection2-r16 } OPTIONAL, -- Need M + pdcch-BlindDetection3-r16 SetupRelease { PDCCH-BlindDetection3-r16 } OPTIONAL, -- Need M + bdFactorR-r16 ENUMERATED {n1} OPTIONAL -- Need R + ]] +} + +PDCCH-BlindDetection ::= INTEGER (1..15) + +DCP-Config-r16 ::= SEQUENCE { + ps-RNTI-r16 RNTI-Value, + ps-Offset-r16 INTEGER (1..120), + sizeDCI-2-6-r16 INTEGER (1..maxDCI-2-6-Size-r16), + ps-PositionDCI-2-6-r16 INTEGER (0..maxDCI-2-6-Size-1-r16), + ps-WakeUp-r16 ENUMERATED {true} OPTIONAL, -- Need S + ps-TransmitPeriodicL1-RSRP-r16 ENUMERATED {true} OPTIONAL, -- Need S + ps-TransmitOtherPeriodicCSI-r16 ENUMERATED {true} OPTIONAL -- Need S +} + +PDSCH-HARQ-ACK-CodebookList-r16 ::= SEQUENCE (SIZE (1..2)) OF ENUMERATED {semiStatic, dynamic} + +PDCCH-BlindDetectionCA-CombIndicator-r16 ::= SEQUENCE { + pdcch-BlindDetectionCA1-r16 INTEGER (1..15), + pdcch-BlindDetectionCA2-r16 INTEGER (1..15) +} + +PDCCH-BlindDetection2-r16 ::= INTEGER (1..15) + +PDCCH-BlindDetection3-r16 ::= INTEGER (1..15) + +-- TAG-PHYSICALCELLGROUPCONFIG-STOP +-- TAG-PLMN-IDENTITY-START + +PLMN-Identity ::= SEQUENCE { + mcc MCC OPTIONAL, -- Cond MCC + mnc MNC +} + +MCC ::= SEQUENCE (SIZE (3)) OF MCC-MNC-Digit + +MNC ::= SEQUENCE (SIZE (2..3)) OF MCC-MNC-Digit + +MCC-MNC-Digit ::= INTEGER (0..9) + + +-- TAG-PLMN-IDENTITY-STOP +-- TAG-PLMN-IDENTITYINFOLIST-START + +PLMN-IdentityInfoList ::= SEQUENCE (SIZE (1..maxPLMN)) OF PLMN-IdentityInfo + +PLMN-IdentityInfo ::= SEQUENCE { + plmn-IdentityList SEQUENCE (SIZE (1..maxPLMN)) OF PLMN-Identity, + trackingAreaCode TrackingAreaCode OPTIONAL, -- Need R + ranac RAN-AreaCode OPTIONAL, -- Need R + cellIdentity CellIdentity, + cellReservedForOperatorUse ENUMERATED {reserved, notReserved}, + ..., + [[ + iab-Support-r16 ENUMERATED {true} OPTIONAL -- Need S + ]] +} +-- TAG-PLMN-IDENTITYINFOLIST-STOP +-- TAG-PLMNIDENTITYLIST2-START + +PLMN-IdentityList2-r16 ::= SEQUENCE (SIZE (1..16)) OF PLMN-Identity + +-- TAG-PLMNIDENTITYLIST2-STOP +-- TAG-PRB-ID-START + +PRB-Id ::= INTEGER (0..maxNrofPhysicalResourceBlocks-1) + +-- TAG-PRB-ID-STOP +-- TAG-PTRS-DOWNLINKCONFIG-START + +PTRS-DownlinkConfig ::= SEQUENCE { + frequencyDensity SEQUENCE (SIZE (2)) OF INTEGER (1..276) OPTIONAL, -- Need S + timeDensity SEQUENCE (SIZE (3)) OF INTEGER (0..29) OPTIONAL, -- Need S + epre-Ratio INTEGER (0..3) OPTIONAL, -- Need S + resourceElementOffset ENUMERATED { offset01, offset10, offset11 } OPTIONAL, -- Need S + ..., + [[ + maxNrofPorts-r16 ENUMERATED {n1, n2} OPTIONAL -- Need R + ]] + +} + +-- TAG-PTRS-DOWNLINKCONFIG-STOP +-- TAG-PTRS-UPLINKCONFIG-START + +PTRS-UplinkConfig ::= SEQUENCE { + transformPrecoderDisabled SEQUENCE { + frequencyDensity SEQUENCE (SIZE (2)) OF INTEGER (1..276) OPTIONAL, -- Need S + timeDensity SEQUENCE (SIZE (3)) OF INTEGER (0..29) OPTIONAL, -- Need S + maxNrofPorts ENUMERATED {n1, n2}, + resourceElementOffset ENUMERATED {offset01, offset10, offset11 } OPTIONAL, -- Need S + ptrs-Power ENUMERATED {p00, p01, p10, p11} + } OPTIONAL, -- Need R + transformPrecoderEnabled SEQUENCE { + sampleDensity SEQUENCE (SIZE (5)) OF INTEGER (1..276), + timeDensityTransformPrecoding ENUMERATED {d2} OPTIONAL -- Need S + } OPTIONAL, -- Need R + ... +} + +-- TAG-PTRS-UPLINKCONFIG-STOP +-- TAG-PUCCH-CONFIG-START + +PUCCH-Config ::= SEQUENCE { + resourceSetToAddModList SEQUENCE (SIZE (1..maxNrofPUCCH-ResourceSets)) OF PUCCH-ResourceSet OPTIONAL, -- Need N + resourceSetToReleaseList SEQUENCE (SIZE (1..maxNrofPUCCH-ResourceSets)) OF PUCCH-ResourceSetId OPTIONAL, -- Need N + resourceToAddModList SEQUENCE (SIZE (1..maxNrofPUCCH-Resources)) OF PUCCH-Resource OPTIONAL, -- Need N + resourceToReleaseList SEQUENCE (SIZE (1..maxNrofPUCCH-Resources)) OF PUCCH-ResourceId OPTIONAL, -- Need N + format1 SetupRelease { PUCCH-FormatConfig } OPTIONAL, -- Need M + format2 SetupRelease { PUCCH-FormatConfig } OPTIONAL, -- Need M + format3 SetupRelease { PUCCH-FormatConfig } OPTIONAL, -- Need M + format4 SetupRelease { PUCCH-FormatConfig } OPTIONAL, -- Need M + schedulingRequestResourceToAddModList SEQUENCE (SIZE (1..maxNrofSR-Resources)) OF SchedulingRequestResourceConfig + OPTIONAL, -- Need N + schedulingRequestResourceToReleaseList SEQUENCE (SIZE (1..maxNrofSR-Resources)) OF SchedulingRequestResourceId + OPTIONAL, -- Need N + multi-CSI-PUCCH-ResourceList SEQUENCE (SIZE (1..2)) OF PUCCH-ResourceId OPTIONAL, -- Need M + dl-DataToUL-ACK SEQUENCE (SIZE (1..8)) OF INTEGER (0..15) OPTIONAL, -- Need M + spatialRelationInfoToAddModList SEQUENCE (SIZE (1..maxNrofSpatialRelationInfos)) OF PUCCH-SpatialRelationInfo + OPTIONAL, -- Need N + spatialRelationInfoToReleaseList SEQUENCE (SIZE (1..maxNrofSpatialRelationInfos)) OF PUCCH-SpatialRelationInfoId + OPTIONAL, -- Need N + pucch-PowerControl PUCCH-PowerControl OPTIONAL, -- Need M + ..., + [[ + resourceToAddModListExt-r16 SEQUENCE (SIZE (1..maxNrofPUCCH-Resources)) OF PUCCH-ResourceExt-r16 OPTIONAL, -- Need N + dl-DataToUL-ACK-r16 SetupRelease { DL-DataToUL-ACK-r16 } OPTIONAL, -- Need M + ul-AccessConfigListForDCI-Format-1-1-r16 SetupRelease { UL-AccessConfigListForDCI-Format1-1-r16 } OPTIONAL, -- Need M + subslotLengthForPUCCH-r16 CHOICE { + normalCP-r16 ENUMERATED {n2,n7}, + extendedCP-r16 ENUMERATED {n2,n6} + } OPTIONAL, -- Need R + dl-DataToUL-ACK-ForDCI-Format1-2-r16 SetupRelease { DL-DataToUL-ACK-ForDCI-Format1-2-r16} OPTIONAL, -- Need M + numberOfBitsForPUCCH-ResourceIndicatorForDCI-Format1-2-r16 INTEGER (0..3) OPTIONAL, -- Need R + dmrs-UplinkTransformPrecodingPUCCH-r16 ENUMERATED {enabled} OPTIONAL, -- Cond PI2-BPSK + spatialRelationInfoToAddModList2-r16 SEQUENCE (SIZE (1..maxNrofSpatialRelationInfosDiff-r16)) OF PUCCH-SpatialRelationInfo + OPTIONAL, -- Need N + spatialRelationInfoToReleaseList2-r16 SEQUENCE (SIZE (1..maxNrofSpatialRelationInfosDiff-r16)) OF PUCCH-SpatialRelationInfoId + OPTIONAL, -- Need N + spatialRelationInfoToAddModListExt-r16 SEQUENCE (SIZE (1..maxNrofSpatialRelationInfos-r16)) OF PUCCH-SpatialRelationInfoExt-r16 + OPTIONAL, -- Need N + spatialRelationInfoToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofSpatialRelationInfos-r16)) OF PUCCH-SpatialRelationInfoId-r16 OPTIONAL, -- Need N + resourceGroupToAddModList-r16 SEQUENCE (SIZE (1..maxNrofPUCCH-ResourceGroups-r16)) OF PUCCH-ResourceGroup-r16 + OPTIONAL, -- Need N + resourceGroupToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofPUCCH-ResourceGroups-r16)) OF PUCCH-ResourceGroupId-r16 + OPTIONAL, -- Need N + sps-PUCCH-AN-List-r16 SetupRelease { SPS-PUCCH-AN-List-r16 } OPTIONAL, -- Need M + schedulingRequestResourceToAddModList-v1610 SEQUENCE (SIZE (1..maxNrofSR-Resources)) OF SchedulingRequestResourceConfig-v1610 + OPTIONAL -- Need N + ]] +} + +PUCCH-FormatConfig ::= SEQUENCE { + interslotFrequencyHopping ENUMERATED {enabled} OPTIONAL, -- Need R + additionalDMRS ENUMERATED {true} OPTIONAL, -- Need R + maxCodeRate PUCCH-MaxCodeRate OPTIONAL, -- Need R + nrofSlots ENUMERATED {n2,n4,n8} OPTIONAL, -- Need S + pi2BPSK ENUMERATED {enabled} OPTIONAL, -- Need R + simultaneousHARQ-ACK-CSI ENUMERATED {true} OPTIONAL -- Need R +} + +PUCCH-MaxCodeRate ::= ENUMERATED {zeroDot08, zeroDot15, zeroDot25, zeroDot35, zeroDot45, zeroDot60, zeroDot80} + +-- A set with one or more PUCCH resources +PUCCH-ResourceSet ::= SEQUENCE { + pucch-ResourceSetId PUCCH-ResourceSetId, + resourceList SEQUENCE (SIZE (1..maxNrofPUCCH-ResourcesPerSet)) OF PUCCH-ResourceId, + maxPayloadSize INTEGER (4..256) OPTIONAL -- Need R +} + +PUCCH-ResourceSetId ::= INTEGER (0..maxNrofPUCCH-ResourceSets-1) + +PUCCH-Resource ::= SEQUENCE { + pucch-ResourceId PUCCH-ResourceId, + startingPRB PRB-Id, + intraSlotFrequencyHopping ENUMERATED { enabled } OPTIONAL, -- Need R + secondHopPRB PRB-Id OPTIONAL, -- Need R + format CHOICE { + format0 PUCCH-format0, + format1 PUCCH-format1, + format2 PUCCH-format2, + format3 PUCCH-format3, + format4 PUCCH-format4 + } +} + +PUCCH-ResourceExt-r16 ::= SEQUENCE { + interlaceAllocation-r16 SEQUENCE { + rb-SetIndex INTEGER (0..4), + interlace0 CHOICE { + scs15 INTEGER (0..9), + scs30 INTEGER (0..4) + } + } OPTIONAL, --Need R + formatExt-v1610 CHOICE { + interlace1-v1610 INTEGER (0..9), + occ-v1610 SEQUENCE { + occ-Length-v1610 ENUMERATED {n2,n4} OPTIONAL, -- Need M + occ-Index-v1610 ENUMERATED {n0,n1,n2,n3} OPTIONAL -- Need M + } + } OPTIONAL, -- Need R + ... +} + +PUCCH-ResourceId ::= INTEGER (0..maxNrofPUCCH-Resources-1) + + +PUCCH-format0 ::= SEQUENCE { + initialCyclicShift INTEGER(0..11), + nrofSymbols INTEGER (1..2), + startingSymbolIndex INTEGER(0..13) +} + +PUCCH-format1 ::= SEQUENCE { + initialCyclicShift INTEGER(0..11), + nrofSymbols INTEGER (4..14), + startingSymbolIndex INTEGER(0..10), + timeDomainOCC INTEGER(0..6) +} + +PUCCH-format2 ::= SEQUENCE { + nrofPRBs INTEGER (1..16), + nrofSymbols INTEGER (1..2), + startingSymbolIndex INTEGER(0..13) +} + +PUCCH-format3 ::= SEQUENCE { + nrofPRBs INTEGER (1..16), + nrofSymbols INTEGER (4..14), + startingSymbolIndex INTEGER(0..10) +} + +PUCCH-format4 ::= SEQUENCE { + nrofSymbols INTEGER (4..14), + occ-Length ENUMERATED {n2,n4}, + occ-Index ENUMERATED {n0,n1,n2,n3}, + startingSymbolIndex INTEGER(0..10) +} + +PUCCH-ResourceGroup-r16 ::= SEQUENCE { + pucch-ResourceGroupId-r16 PUCCH-ResourceGroupId-r16, + resourcePerGroupList-r16 SEQUENCE (SIZE (1..maxNrofPUCCH-ResourcesPerGroup-r16)) OF PUCCH-ResourceId +} + +PUCCH-ResourceGroupId-r16 ::= INTEGER (0..maxNrofPUCCH-ResourceGroups-1-r16) + +DL-DataToUL-ACK-r16 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (-1..15) + +DL-DataToUL-ACK-ForDCI-Format1-2-r16 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (0..15) + +UL-AccessConfigListForDCI-Format1-1-r16 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..15) + +-- TAG-PUCCH-CONFIG-STOP +-- TAG-PUCCH-CONFIGCOMMON-START + +PUCCH-ConfigCommon ::= SEQUENCE { + pucch-ResourceCommon INTEGER (0..15) OPTIONAL, -- Cond InitialBWP-Only + pucch-GroupHopping ENUMERATED { neither, enable, disable }, + hoppingId INTEGER (0..1023) OPTIONAL, -- Need R + p0-nominal INTEGER (-202..24) OPTIONAL, -- Need R + ... +} + +-- TAG-PUCCH-CONFIGCOMMON-STOP +-- TAG-PUCCH-CONFIGURATIONLIST-START + +PUCCH-ConfigurationList-r16 ::= SEQUENCE (SIZE (1..2)) OF PUCCH-Config + +-- TAG-PUCCH-CONFIGURATIONLIST-STOP +-- TAG-PUCCH-PATHLOSSREFERENCERS-ID-START + +PUCCH-PathlossReferenceRS-Id ::= INTEGER (0..maxNrofPUCCH-PathlossReferenceRSs-1) + +PUCCH-PathlossReferenceRS-Id-v1610 ::= INTEGER (maxNrofPUCCH-PathlossReferenceRSs..maxNrofPUCCH-PathlossReferenceRSs-1-r16) + +-- TAG-PUCCH-PATHLOSSREFERENCERS-ID-STOP +-- TAG-PUCCH-POWERCONTROL-START +PUCCH-PowerControl ::= SEQUENCE { + deltaF-PUCCH-f0 INTEGER (-16..15) OPTIONAL, -- Need R + deltaF-PUCCH-f1 INTEGER (-16..15) OPTIONAL, -- Need R + deltaF-PUCCH-f2 INTEGER (-16..15) OPTIONAL, -- Need R + deltaF-PUCCH-f3 INTEGER (-16..15) OPTIONAL, -- Need R + deltaF-PUCCH-f4 INTEGER (-16..15) OPTIONAL, -- Need R + p0-Set SEQUENCE (SIZE (1..maxNrofPUCCH-P0-PerSet)) OF P0-PUCCH OPTIONAL, -- Need M + pathlossReferenceRSs SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSs)) OF PUCCH-PathlossReferenceRS + OPTIONAL, -- Need M + twoPUCCH-PC-AdjustmentStates ENUMERATED {twoStates} OPTIONAL, -- Need S + ..., + [[ + pathlossReferenceRSs-v1610 SetupRelease { PathlossReferenceRSs-v1610 } OPTIONAL -- Need M + ]] +} + +P0-PUCCH ::= SEQUENCE { + p0-PUCCH-Id P0-PUCCH-Id, + p0-PUCCH-Value INTEGER (-16..15) +} + +P0-PUCCH-Id ::= INTEGER (1..8) + +PathlossReferenceRSs-v1610 ::= SEQUENCE (SIZE (1..maxNrofPUCCH-PathlossReferenceRSsDiff-r16)) OF PUCCH-PathlossReferenceRS-r16 + +PUCCH-PathlossReferenceRS ::= SEQUENCE { + pucch-PathlossReferenceRS-Id PUCCH-PathlossReferenceRS-Id, + referenceSignal CHOICE { + ssb-Index SSB-Index, + csi-RS-Index NZP-CSI-RS-ResourceId + } +} + +PUCCH-PathlossReferenceRS-r16 ::= SEQUENCE { + pucch-PathlossReferenceRS-Id-r16 PUCCH-PathlossReferenceRS-Id-v1610, + referenceSignal-r16 CHOICE { + ssb-Index-r16 SSB-Index, + csi-RS-Index-r16 NZP-CSI-RS-ResourceId + } +} + +-- TAG-PUCCH-POWERCONTROL-STOP +-- TAG-PUCCH-SPATIALRELATIONINFO-START + +PUCCH-SpatialRelationInfo ::= SEQUENCE { + pucch-SpatialRelationInfoId PUCCH-SpatialRelationInfoId, + servingCellId ServCellIndex OPTIONAL, -- Need S + referenceSignal CHOICE { + ssb-Index SSB-Index, + csi-RS-Index NZP-CSI-RS-ResourceId, + srs PUCCH-SRS + }, + pucch-PathlossReferenceRS-Id PUCCH-PathlossReferenceRS-Id, + p0-PUCCH-Id P0-PUCCH-Id, + closedLoopIndex ENUMERATED { i0, i1 } +} + +PUCCH-SpatialRelationInfoExt-r16 ::= SEQUENCE { + pucch-SpatialRelationInfoId-v1610 PUCCH-SpatialRelationInfoId-v1610 OPTIONAL, -- Cond SetupOnly + pucch-PathlossReferenceRS-Id-v1610 PUCCH-PathlossReferenceRS-Id-v1610 OPTIONAL, --Need R + ... +} + +PUCCH-SRS ::= SEQUENCE { + resource SRS-ResourceId, + uplinkBWP BWP-Id +} +-- TAG-PUCCH-SPATIALRELATIONINFO-STOP +-- TAG-PUCCH-SPATIALRELATIONINFO-START + +PUCCH-SpatialRelationInfoId ::= INTEGER (1..maxNrofSpatialRelationInfos) + +PUCCH-SpatialRelationInfoId-r16 ::= INTEGER (1..maxNrofSpatialRelationInfos-r16) + +PUCCH-SpatialRelationInfoId-v1610::= INTEGER (maxNrofSpatialRelationInfos-plus-1..maxNrofSpatialRelationInfos-r16) + +-- TAG-PUCCH-SPATIALRELATIONINFO-STOP +-- TAG-PUCCH-TPC-COMMANDCONFIG-START + +PUCCH-TPC-CommandConfig ::= SEQUENCE { + tpc-IndexPCell INTEGER (1..15) OPTIONAL, -- Cond PDCCH-OfSpcell + tpc-IndexPUCCH-SCell INTEGER (1..15) OPTIONAL, -- Cond PDCCH-ofSpCellOrPUCCH-SCell + ... +} + +-- TAG-PUCCH-TPC-COMMANDCONFIG-STOP +-- TAG-PUSCH-CONFIG-START + +PUSCH-Config ::= SEQUENCE { + dataScramblingIdentityPUSCH INTEGER (0..1023) OPTIONAL, -- Need S + txConfig ENUMERATED {codebook, nonCodebook} OPTIONAL, -- Need S + dmrs-UplinkForPUSCH-MappingTypeA SetupRelease { DMRS-UplinkConfig } OPTIONAL, -- Need M + dmrs-UplinkForPUSCH-MappingTypeB SetupRelease { DMRS-UplinkConfig } OPTIONAL, -- Need M + pusch-PowerControl PUSCH-PowerControl OPTIONAL, -- Need M + frequencyHopping ENUMERATED {intraSlot, interSlot} OPTIONAL, -- Need S + frequencyHoppingOffsetLists SEQUENCE (SIZE (1..4)) OF INTEGER (1.. maxNrofPhysicalResourceBlocks-1) + OPTIONAL, -- Need M + resourceAllocation ENUMERATED { resourceAllocationType0, resourceAllocationType1, dynamicSwitch}, + pusch-TimeDomainAllocationList SetupRelease { PUSCH-TimeDomainResourceAllocationList } OPTIONAL, -- Need M + pusch-AggregationFactor ENUMERATED { n2, n4, n8 } OPTIONAL, -- Need S + mcs-Table ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + mcs-TableTransformPrecoder ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + transformPrecoder ENUMERATED {enabled, disabled} OPTIONAL, -- Need S + codebookSubset ENUMERATED {fullyAndPartialAndNonCoherent, partialAndNonCoherent,nonCoherent} + OPTIONAL, -- Cond codebookBased + maxRank INTEGER (1..4) OPTIONAL, -- Cond codebookBased + rbg-Size ENUMERATED { config2} OPTIONAL, -- Need S + uci-OnPUSCH SetupRelease { UCI-OnPUSCH} OPTIONAL, -- Need M + tp-pi2BPSK ENUMERATED {enabled} OPTIONAL, -- Need S + ..., + [[ + minimumSchedulingOffsetK2-r16 SetupRelease { MinSchedulingOffsetK2-Values-r16 } OPTIONAL, -- Need M + ul-AccessConfigListForDCI-Format0-1-r16 SetupRelease { UL-AccessConfigListForDCI-Format0-1-r16 } OPTIONAL, -- Need M + -- Start of the parameters for DCI format 0_2 introduced in V16.1.0 + harq-ProcessNumberSizeForDCI-Format0-2-r16 INTEGER (0..4) OPTIONAL, -- Need R + dmrs-SequenceInitializationForDCI-Format0-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + numberOfBitsForRV-ForDCI-Format0-2-r16 INTEGER (0..2) OPTIONAL, -- Need R + antennaPortsFieldPresenceForDCI-Format0-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + dmrs-UplinkForPUSCH-MappingTypeA-ForDCI-Format0-2-r16 SetupRelease { DMRS-UplinkConfig } OPTIONAL, -- Need M + dmrs-UplinkForPUSCH-MappingTypeB-ForDCI-Format0-2-r16 SetupRelease { DMRS-UplinkConfig } OPTIONAL, -- Need M + frequencyHoppingForDCI-Format0-2-r16 CHOICE { + pusch-RepTypeA ENUMERATED {intraSlot, interSlot}, + pusch-RepTypeB ENUMERATED {interRepetition, interSlot} + } OPTIONAL, -- Need S + frequencyHoppingOffsetListsForDCI-Format0-2-r16 SetupRelease { FrequencyHoppingOffsetListsForDCI-Format0-2-r16} OPTIONAL, -- Need M + codebookSubsetForDCI-Format0-2-r16 ENUMERATED {fullyAndPartialAndNonCoherent, partialAndNonCoherent,nonCoherent} + OPTIONAL, -- Cond codebookBased + invalidSymbolPatternIndicatorForDCI-Format0-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + maxRankForDCI-Format0-2-r16 INTEGER (1..4) OPTIONAL, -- Cond codebookBased + mcs-TableForDCI-Format0-2-r16 ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + mcs-TableTransformPrecoderForDCI-Format0-2-r16 ENUMERATED {qam256, qam64LowSE} OPTIONAL, -- Need S + priorityIndicatorForDCI-Format0-2-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + pusch-RepTypeIndicatorForDCI-Format0-2-r16 ENUMERATED { pusch-RepTypeA, pusch-RepTypeB} OPTIONAL, -- Need R + resourceAllocationForDCI-Format0-2-r16 ENUMERATED { resourceAllocationType0, resourceAllocationType1, dynamicSwitch} + OPTIONAL, -- Need M + resourceAllocationType1GranularityForDCI-Format0-2-r16 ENUMERATED { n2,n4,n8,n16 } OPTIONAL, -- Need S + uci-OnPUSCH-ListForDCI-Format0-2-r16 SetupRelease { UCI-OnPUSCH-ListForDCI-Format0-2-r16} OPTIONAL, -- Need M + pusch-TimeDomainAllocationListForDCI-Format0-2-r16 SetupRelease { PUSCH-TimeDomainResourceAllocationList-r16 } + OPTIONAL, -- Need M + -- End of the parameters for DCI format 0_2 introduced in V16.1.0 + -- Start of the parameters for DCI format 0_1 introduced in V16.1.0 + pusch-TimeDomainAllocationListForDCI-Format0-1-r16 SetupRelease { PUSCH-TimeDomainResourceAllocationList-r16 } + OPTIONAL, -- Need M + invalidSymbolPatternIndicatorForDCI-Format0-1-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + priorityIndicatorForDCI-Format0-1-r16 ENUMERATED {enabled} OPTIONAL, -- Need S + pusch-RepTypeIndicatorForDCI-Format0-1-r16 ENUMERATED { pusch-RepTypeA, pusch-RepTypeB} OPTIONAL, -- Need R + frequencyHoppingForDCI-Format0-1-r16 ENUMERATED {interRepetition, interSlot} OPTIONAL, -- Cond RepTypeB + uci-OnPUSCH-ListForDCI-Format0-1-r16 SetupRelease { UCI-OnPUSCH-ListForDCI-Format0-1-r16 } OPTIONAL, -- Need M + -- End of the parameters for DCI format 0_1 introduced in V16.1.0 + invalidSymbolPattern-r16 InvalidSymbolPattern-r16 OPTIONAL, -- Need S + pusch-PowerControl-v1610 SetupRelease {PUSCH-PowerControl-v1610} OPTIONAL, -- Need M + ul-FullPowerTransmission-r16 ENUMERATED {fullpower, fullpowerMode1, fullpoweMode2} OPTIONAL, -- Need R + pusch-TimeDomainAllocationListForMultiPUSCH-r16 SetupRelease { PUSCH-TimeDomainResourceAllocationList-r16 } + OPTIONAL, -- Need M + numberOfInvalidSymbolsForDL-UL-Switching-r16 INTEGER (1..4) OPTIONAL -- Cond RepTypeB2 + ]] +} + +UCI-OnPUSCH ::= SEQUENCE { + betaOffsets CHOICE { + dynamic SEQUENCE (SIZE (4)) OF BetaOffsets, + semiStatic BetaOffsets + } OPTIONAL, -- Need M + scaling ENUMERATED { f0p5, f0p65, f0p8, f1 } +} + +MinSchedulingOffsetK2-Values-r16 ::= SEQUENCE (SIZE (1..maxNrOfMinSchedulingOffsetValues-r16)) OF INTEGER (0..maxK2-SchedulingOffset-r16) + +UCI-OnPUSCH-ForDCI-Format0-2-r16 ::= SEQUENCE { + betaOffsetsForDCI-Format0-2-r16 CHOICE { + dynamicForDCI-Format0-2-r16 CHOICE { + oneBit-r16 SEQUENCE (SIZE (2)) OF BetaOffsets, + twoBits-r16 SEQUENCE (SIZE (4)) OF BetaOffsets + }, + semiStaticForDCI-Format0-2-r16 BetaOffsets + } OPTIONAL, -- Need M + scalingForDCI-Format0-2-r16 ENUMERATED { f0p5, f0p65, f0p8, f1 } +} + +FrequencyHoppingOffsetListsForDCI-Format0-2-r16 ::= SEQUENCE (SIZE (1..4)) OF INTEGER (1.. maxNrofPhysicalResourceBlocks-1) + +UCI-OnPUSCH-ListForDCI-Format0-2-r16 ::= SEQUENCE (SIZE (1..2)) OF UCI-OnPUSCH-ForDCI-Format0-2-r16 + +UCI-OnPUSCH-ListForDCI-Format0-1-r16 ::= SEQUENCE (SIZE (1..2)) OF UCI-OnPUSCH + +UL-AccessConfigListForDCI-Format0-1-r16 ::= SEQUENCE (SIZE (1..64)) OF INTEGER (0..63) + +-- TAG-PUSCH-CONFIG-STOP +-- TAG-PUSCH-CONFIGCOMMON-START + +PUSCH-ConfigCommon ::= SEQUENCE { + groupHoppingEnabledTransformPrecoding ENUMERATED {enabled} OPTIONAL, -- Need R + pusch-TimeDomainAllocationList PUSCH-TimeDomainResourceAllocationList OPTIONAL, -- Need R + msg3-DeltaPreamble INTEGER (-1..6) OPTIONAL, -- Need R + p0-NominalWithGrant INTEGER (-202..24) OPTIONAL, -- Need R + ... +} + +-- TAG-PUSCH-CONFIGCOMMON-STOP +-- TAG-PUSCH-POWERCONTROL-START + +PUSCH-PowerControl ::= SEQUENCE { + tpc-Accumulation ENUMERATED { disabled } OPTIONAL, -- Need S + msg3-Alpha Alpha OPTIONAL, -- Need S + p0-NominalWithoutGrant INTEGER (-202..24) OPTIONAL, -- Need M + p0-AlphaSets SEQUENCE (SIZE (1..maxNrofP0-PUSCH-AlphaSets)) OF P0-PUSCH-AlphaSet OPTIONAL, -- Need M + pathlossReferenceRSToAddModList SEQUENCE (SIZE (1..maxNrofPUSCH-PathlossReferenceRSs)) OF PUSCH-PathlossReferenceRS + OPTIONAL, -- Need N + pathlossReferenceRSToReleaseList SEQUENCE (SIZE (1..maxNrofPUSCH-PathlossReferenceRSs)) OF PUSCH-PathlossReferenceRS-Id + OPTIONAL, -- Need N + twoPUSCH-PC-AdjustmentStates ENUMERATED {twoStates} OPTIONAL, -- Need S + deltaMCS ENUMERATED {enabled} OPTIONAL, -- Need S + sri-PUSCH-MappingToAddModList SEQUENCE (SIZE (1..maxNrofSRI-PUSCH-Mappings)) OF SRI-PUSCH-PowerControl + OPTIONAL, -- Need N + sri-PUSCH-MappingToReleaseList SEQUENCE (SIZE (1..maxNrofSRI-PUSCH-Mappings)) OF SRI-PUSCH-PowerControlId + OPTIONAL -- Need N +} + +P0-PUSCH-AlphaSet ::= SEQUENCE { + p0-PUSCH-AlphaSetId P0-PUSCH-AlphaSetId, + p0 INTEGER (-16..15) OPTIONAL, -- Need S + alpha Alpha OPTIONAL -- Need S +} + +P0-PUSCH-AlphaSetId ::= INTEGER (0..maxNrofP0-PUSCH-AlphaSets-1) + +PUSCH-PathlossReferenceRS ::= SEQUENCE { + pusch-PathlossReferenceRS-Id PUSCH-PathlossReferenceRS-Id, + referenceSignal CHOICE { + ssb-Index SSB-Index, + csi-RS-Index NZP-CSI-RS-ResourceId + } +} + +PUSCH-PathlossReferenceRS-r16 ::= SEQUENCE { + pusch-PathlossReferenceRS-Id-r16 PUSCH-PathlossReferenceRS-Id-v1610, + referenceSignal-r16 CHOICE { + ssb-Index-r16 SSB-Index, + csi-RS-Index-r16 NZP-CSI-RS-ResourceId + } +} + +PUSCH-PathlossReferenceRS-Id ::= INTEGER (0..maxNrofPUSCH-PathlossReferenceRSs-1) + +PUSCH-PathlossReferenceRS-Id-v1610 ::= INTEGER (maxNrofPUSCH-PathlossReferenceRSs..maxNrofPUSCH-PathlossReferenceRSs-1-r16) + +SRI-PUSCH-PowerControl ::= SEQUENCE { + sri-PUSCH-PowerControlId SRI-PUSCH-PowerControlId, + sri-PUSCH-PathlossReferenceRS-Id PUSCH-PathlossReferenceRS-Id, + sri-P0-PUSCH-AlphaSetId P0-PUSCH-AlphaSetId, + sri-PUSCH-ClosedLoopIndex ENUMERATED { i0, i1 } +} + +SRI-PUSCH-PowerControlId ::= INTEGER (0..maxNrofSRI-PUSCH-Mappings-1) + +PUSCH-PowerControl-v1610 ::= SEQUENCE { + pathlossReferenceRSToAddModList2-r16 SEQUENCE (SIZE (1..maxNrofPUSCH-PathlossReferenceRSsDiff-r16)) OF PUSCH-PathlossReferenceRS-r16 + OPTIONAL, -- Need N + pathlossReferenceRSToReleaseList2-r16 SEQUENCE (SIZE (1..maxNrofPUSCH-PathlossReferenceRSsDiff-r16)) OF PUSCH-PathlossReferenceRS-Id-v1610 + OPTIONAL, -- Need N + p0-PUSCH-SetList-r16 SEQUENCE (SIZE (1..maxNrofSRI-PUSCH-Mappings)) OF P0-PUSCH-Set-r16 OPTIONAL, -- Need R + olpc-ParameterSet SEQUENCE { + olpc-ParameterSetForDCI-Format0-1-r16 INTEGER (1..2) OPTIONAL, -- Need R + olpc-ParameterSetForDCI-Format0-2-r16 INTEGER (1..2) OPTIONAL -- Need R + } OPTIONAL, -- Need M + ... +} + +P0-PUSCH-Set-r16 ::= SEQUENCE { + p0-PUSCH-SetId-r16 P0-PUSCH-SetId-r16, + p0-List-r16 SEQUENCE (SIZE (1..maxNrofP0-PUSCH-Set-r16)) OF P0-PUSCH-r16 OPTIONAL, -- Need R + ... +} + +P0-PUSCH-SetId-r16 ::= INTEGER (0..maxNrofSRI-PUSCH-Mappings-1) + +P0-PUSCH-r16 ::= INTEGER (-16..15) + +-- TAG-PUSCH-POWERCONTROL-STOP +-- TAG-PUSCH-SERVINGCELLCONFIG-START + +PUSCH-ServingCellConfig ::= SEQUENCE { + codeBlockGroupTransmission SetupRelease { PUSCH-CodeBlockGroupTransmission } OPTIONAL, -- Need M + rateMatching ENUMERATED {limitedBufferRM} OPTIONAL, -- Need S + xOverhead ENUMERATED {xoh6, xoh12, xoh18} OPTIONAL, -- Need S + ..., + [[ + maxMIMO-Layers INTEGER (1..4) OPTIONAL, -- Need M + processingType2Enabled BOOLEAN OPTIONAL -- Need M + ]], + [[ + maxMIMO-LayersForDCI-Format0-2-r16 SetupRelease { MaxMIMO-LayersForDCI-Format0-2-r16} OPTIONAL -- Need M + ]] +} + +PUSCH-CodeBlockGroupTransmission ::= SEQUENCE { + maxCodeBlockGroupsPerTransportBlock ENUMERATED {n2, n4, n6, n8}, + ... +} + +MaxMIMO-LayersForDCI-Format0-2-r16 ::= INTEGER (1..4) + +-- TAG-PUSCH-SERVINGCELLCONFIG-STOP +-- TAG-PUSCH-TIMEDOMAINRESOURCEALLOCATIONLIST-START + +PUSCH-TimeDomainResourceAllocationList ::= SEQUENCE (SIZE(1..maxNrofUL-Allocations)) OF PUSCH-TimeDomainResourceAllocation + +PUSCH-TimeDomainResourceAllocation ::= SEQUENCE { + k2 INTEGER(0..32) OPTIONAL, -- Need S + mappingType ENUMERATED {typeA, typeB}, + startSymbolAndLength INTEGER (0..127) +} + +PUSCH-TimeDomainResourceAllocationList-r16 ::= SEQUENCE (SIZE(1..maxNrofUL-Allocations-r16)) OF PUSCH-TimeDomainResourceAllocation-r16 + +PUSCH-TimeDomainResourceAllocation-r16 ::= SEQUENCE { + k2-r16 INTEGER(0..32) OPTIONAL, -- Need S + puschAllocationList-r16 SEQUENCE (SIZE(1..maxNrofMultiplePUSCHs-r16)) OF PUSCH-Allocation-r16, + ... +} + +PUSCH-Allocation-r16 ::= SEQUENCE { + mappingType-r16 ENUMERATED {typeA, typeB} OPTIONAL, -- Cond NotFormat01-02-Or-TypeA + startSymbolAndLength-r16 INTEGER (0..127) OPTIONAL, -- Cond NotFormat01-02-Or-TypeA + startSymbol-r16 INTEGER (0..13) OPTIONAL, -- Cond RepTypeB + length-r16 INTEGER (1..14) OPTIONAL, -- Cond RepTypeB + numberOfRepetitions-r16 ENUMERATED {n1, n2, n3, n4, n7, n8, n12, n16} OPTIONAL, -- Cond Format01-02 + ... +} + +-- TAG-PUSCH-TIMEDOMAINRESOURCEALLOCATIONLIST-STOP +-- TAG-PUSCH-TPC-COMMANDCONFIG-START + +PUSCH-TPC-CommandConfig ::= SEQUENCE { + tpc-Index INTEGER (1..15) OPTIONAL, -- Cond SUL + tpc-IndexSUL INTEGER (1..15) OPTIONAL, -- Cond SUL-Only + targetCell ServCellIndex OPTIONAL, -- Need S + ... +} + +-- TAG-PUSCH-TPC-COMMANDCONFIG-STOP +-- TAG-Q-OFFSETRANGE-START + +Q-OffsetRange ::= ENUMERATED { + dB-24, dB-22, dB-20, dB-18, dB-16, dB-14, + dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3, + dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5, + dB6, dB8, dB10, dB12, dB14, dB16, dB18, + dB20, dB22, dB24} + +-- TAG-Q-OFFSETRANGE-STOP +-- TAG-Q-QUALMIN-START + +Q-QualMin ::= INTEGER (-43..-12) + +-- TAG-Q-QUALMIN-STOP +-- TAG-Q-RXLEVMIN-START + +Q-RxLevMin ::= INTEGER (-70..-22) + +-- TAG-Q-RXLEVMIN-STOP +-- TAG-QUANTITYCONFIG-START + + +QuantityConfig ::= SEQUENCE { + quantityConfigNR-List SEQUENCE (SIZE (1..maxNrofQuantityConfig)) OF QuantityConfigNR OPTIONAL, -- Need M + ..., + [[ + quantityConfigEUTRA FilterConfig OPTIONAL -- Need M + ]], + [[ + quantityConfigUTRA-FDD-r16 QuantityConfigUTRA-FDD-r16 OPTIONAL, -- Need M + quantityConfigCLI-r16 FilterConfigCLI-r16 OPTIONAL -- Need M + ]] +} + +QuantityConfigNR::= SEQUENCE { + quantityConfigCell QuantityConfigRS, + quantityConfigRS-Index QuantityConfigRS OPTIONAL -- Need M +} + +QuantityConfigRS ::= SEQUENCE { + ssb-FilterConfig FilterConfig, + csi-RS-FilterConfig FilterConfig +} + +FilterConfig ::= SEQUENCE { + filterCoefficientRSRP FilterCoefficient DEFAULT fc4, + filterCoefficientRSRQ FilterCoefficient DEFAULT fc4, + filterCoefficientRS-SINR FilterCoefficient DEFAULT fc4 +} + +FilterConfigCLI-r16 ::= SEQUENCE { + filterCoefficientSRS-RSRP-r16 FilterCoefficient DEFAULT fc4, + filterCoefficientCLI-RSSI-r16 FilterCoefficient DEFAULT fc4 +} + +QuantityConfigUTRA-FDD-r16 ::= SEQUENCE { + filterCoefficientRSCP-r16 FilterCoefficient DEFAULT fc4, + filterCoefficientEcNO-r16 FilterCoefficient DEFAULT fc4 +} + +-- TAG-QUANTITYCONFIG-STOP +-- TAG-RACH-CONFIGCOMMON-START + +RACH-ConfigCommon ::= SEQUENCE { + rach-ConfigGeneric RACH-ConfigGeneric, + totalNumberOfRA-Preambles INTEGER (1..63) OPTIONAL, -- Need S + ssb-perRACH-OccasionAndCB-PreamblesPerSSB CHOICE { + oneEighth ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + oneFourth ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + oneHalf ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + one ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + two ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32}, + four INTEGER (1..16), + eight INTEGER (1..8), + sixteen INTEGER (1..4) + } OPTIONAL, -- Need M + + groupBconfigured SEQUENCE { + ra-Msg3SizeGroupA ENUMERATED {b56, b144, b208, b256, b282, b480, b640, + b800, b1000, b72, spare6, spare5,spare4, spare3, spare2, spare1}, + messagePowerOffsetGroupB ENUMERATED { minusinfinity, dB0, dB5, dB8, dB10, dB12, dB15, dB18}, + numberOfRA-PreamblesGroupA INTEGER (1..64) + } OPTIONAL, -- Need R + ra-ContentionResolutionTimer ENUMERATED { sf8, sf16, sf24, sf32, sf40, sf48, sf56, sf64}, + rsrp-ThresholdSSB RSRP-Range OPTIONAL, -- Need R + rsrp-ThresholdSSB-SUL RSRP-Range OPTIONAL, -- Cond SUL + prach-RootSequenceIndex CHOICE { + l839 INTEGER (0..837), + l139 INTEGER (0..137) + }, + msg1-SubcarrierSpacing SubcarrierSpacing OPTIONAL, -- Cond L139 + restrictedSetConfig ENUMERATED {unrestrictedSet, restrictedSetTypeA, restrictedSetTypeB}, + msg3-transformPrecoder ENUMERATED {enabled} OPTIONAL, -- Need R + ..., + [[ + ra-PrioritizationForAccessIdentity SEQUENCE { + ra-Prioritization-r16 RA-Prioritization, + ra-PrioritizationForAI-r16 BIT STRING (SIZE (2)) + } OPTIONAL, -- Cond InitialBWP-Only + prach-RootSequenceIndex-r16 CHOICE { + l571 INTEGER (0..569), + l1151 INTEGER (0..1149) + } OPTIONAL -- Need R + ]] +} + +-- TAG-RACH-CONFIGCOMMON-STOP +-- TAG-RACH-CONFIGCOMMONTWOSTEPRA-START + +RACH-ConfigCommonTwoStepRA-r16 ::= SEQUENCE { + rach-ConfigGenericTwoStepRA-r16 RACH-ConfigGenericTwoStepRA-r16, + msgA-TotalNumberOfRA-Preambles-r16 INTEGER (1..63) OPTIONAL, -- Need S + msgA-SSB-PerRACH-OccasionAndCB-PreamblesPerSSB-r16 CHOICE { + oneEighth ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + oneFourth ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + oneHalf ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + one ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32,n36,n40,n44,n48,n52,n56,n60,n64}, + two ENUMERATED {n4,n8,n12,n16,n20,n24,n28,n32}, + four INTEGER (1..16), + eight INTEGER (1..8), + sixteen INTEGER (1..4) + } OPTIONAL, -- Cond 2StepOnly + msgA-CB-PreamblesPerSSB-PerSharedRO-r16 INTEGER (1..60) OPTIONAL, -- Cond SharedRO + msgA-SSB-SharedRO-MaskIndex-r16 INTEGER (1..15) OPTIONAL, -- Need S + groupB-ConfiguredTwoStepRA-r16 GroupB-ConfiguredTwoStepRA-r16 OPTIONAL, -- Need S + msgA-PRACH-RootSequenceIndex-r16 CHOICE { + l839 INTEGER (0..837), + l139 INTEGER (0..137), + l571 INTEGER (0..569), + l1151 INTEGER (0..1149) + } OPTIONAL, -- Cond 2StepOnly + msgA-TransMax-r16 ENUMERATED {n1, n2, n4, n6, n8, n10, n20, n50, n100, n200} OPTIONAL, -- Need R + msgA-RSRP-Threshold-r16 RSRP-Range OPTIONAL, -- Cond 2Step4Step + msgA-RSRP-ThresholdSSB-r16 RSRP-Range OPTIONAL, -- Need R + msgA-SubcarrierSpacing-r16 SubcarrierSpacing OPTIONAL, -- Cond 2StepOnlyL139 + msgA-RestrictedSetConfig-r16 ENUMERATED {unrestrictedSet, restrictedSetTypeA, + restrictedSetTypeB} OPTIONAL, -- Cond 2StepOnly + ra-PrioritizationForAccessIdentityTwoStep-r16 SEQUENCE { + ra-Prioritization-r16 RA-Prioritization, + ra-PrioritizationForAI-r16 BIT STRING (SIZE (2)) + } OPTIONAL, -- Cond InitialBWP-Only + ra-ContentionResolutionTimer-r16 ENUMERATED {sf8, sf16, sf24, sf32, sf40, sf48, sf56, sf64} OPTIONAL, -- Cond 2StepOnly + ... +} + +GroupB-ConfiguredTwoStepRA-r16 ::= SEQUENCE { + ra-MsgA-SizeGroupA ENUMERATED {b56, b144, b208, b256, b282, b480, b640, b800, + b1000, b72, spare6, spare5, spare4, spare3, spare2, spare1}, + messagePowerOffsetGroupB ENUMERATED {minusinfinity, dB0, dB5, dB8, dB10, dB12, dB15, dB18}, + numberofRA-PreamblesGroupA INTEGER (1..64) +} + +-- TAG-RACH-CONFIGCOMMONTWOSTEPRA-STOP +-- TAG-RACH-CONFIGDEDICATED-START + + +RACH-ConfigDedicated ::= SEQUENCE { + cfra CFRA OPTIONAL, -- Need S + ra-Prioritization RA-Prioritization OPTIONAL, -- Need N + ..., + [[ + ra-PrioritizationTwoStep-r16 RA-Prioritization OPTIONAL, -- Need N + cfra-TwoStep-r16 CFRA-TwoStep-r16 OPTIONAL -- Need S + ]] +} + +CFRA ::= SEQUENCE { + occasions SEQUENCE { + rach-ConfigGeneric RACH-ConfigGeneric, + ssb-perRACH-Occasion ENUMERATED {oneEighth, oneFourth, oneHalf, one, two, four, eight, sixteen} + OPTIONAL -- Cond Mandatory + } OPTIONAL, -- Need S + resources CHOICE { + ssb SEQUENCE { + ssb-ResourceList SEQUENCE (SIZE(1..maxRA-SSB-Resources)) OF CFRA-SSB-Resource, + ra-ssb-OccasionMaskIndex INTEGER (0..15) + }, + csirs SEQUENCE { + csirs-ResourceList SEQUENCE (SIZE(1..maxRA-CSIRS-Resources)) OF CFRA-CSIRS-Resource, + rsrp-ThresholdCSI-RS RSRP-Range + } + }, + ..., + [[ + totalNumberOfRA-Preambles INTEGER (1..63) OPTIONAL -- Cond Occasions + ]] +} + +CFRA-TwoStep-r16 ::= SEQUENCE { + occasionsTwoStepRA-r16 SEQUENCE { + rach-ConfigGenericTwoStepRA-r16 RACH-ConfigGenericTwoStepRA-r16, + ssb-PerRACH-OccasionTwoStepRA-r16 ENUMERATED {oneEighth, oneFourth, oneHalf, one, + two, four, eight, sixteen} + } OPTIONAL, -- Need S + msgA-CFRA-PUSCH-r16 MsgA-PUSCH-Resource-r16, + msgA-TransMax-r16 ENUMERATED {n1, n2, n4, n6, n8, n10, n20, n50, n100, n200} OPTIONAL, -- Need S + resourcesTwoStep-r16 SEQUENCE { + ssb-ResourceList SEQUENCE (SIZE(1..maxRA-SSB-Resources)) OF CFRA-SSB-Resource, + ra-ssb-OccasionMaskIndex INTEGER (0..15) + }, + ... +} + +CFRA-SSB-Resource ::= SEQUENCE { + ssb SSB-Index, + ra-PreambleIndex INTEGER (0..63), + ..., + [[ + msgA-PUSCH-resource-Index-r16 INTEGER (0..3071) OPTIONAL -- Cond 2StepCFRA + ]] + +} + +CFRA-CSIRS-Resource ::= SEQUENCE { + csi-RS CSI-RS-Index, + ra-OccasionList SEQUENCE (SIZE(1..maxRA-OccasionsPerCSIRS)) OF INTEGER (0..maxRA-Occasions-1), + ra-PreambleIndex INTEGER (0..63), + ... +} + +-- TAG-RACH-CONFIGDEDICATED-STOP +-- TAG-RACH-CONFIGGENERIC-START + +RACH-ConfigGeneric ::= SEQUENCE { + prach-ConfigurationIndex INTEGER (0..255), + msg1-FDM ENUMERATED {one, two, four, eight}, + msg1-FrequencyStart INTEGER (0..maxNrofPhysicalResourceBlocks-1), + zeroCorrelationZoneConfig INTEGER(0..15), + preambleReceivedTargetPower INTEGER (-202..-60), + preambleTransMax ENUMERATED {n3, n4, n5, n6, n7, n8, n10, n20, n50, n100, n200}, + powerRampingStep ENUMERATED {dB0, dB2, dB4, dB6}, + ra-ResponseWindow ENUMERATED {sl1, sl2, sl4, sl8, sl10, sl20, sl40, sl80}, + ..., + [[ + prach-ConfigurationPeriodScaling-IAB-r16 ENUMERATED {scf1,scf2,scf4,scf8,scf16,scf32,scf64} OPTIONAL, -- Need R + prach-ConfigurationFrameOffset-IAB-r16 INTEGER (0..63) OPTIONAL, -- Need R + prach-ConfigurationSOffset-IAB-r16 INTEGER (0..39) OPTIONAL, -- Need R + ra-ResponseWindow-v1610 ENUMERATED { sl60, sl160} OPTIONAL, -- Need R + prach-ConfigurationIndex-v1610 INTEGER (256..262) OPTIONAL -- Need R + ]] +} + +-- TAG-RACH-CONFIGGENERIC-STOP +-- TAG-RACH-CONFIGGENERICTWOSTEPRA-START + +RACH-ConfigGenericTwoStepRA-r16 ::= SEQUENCE { + msgA-PRACH-ConfigurationIndex-r16 INTEGER (0..262) OPTIONAL, -- Cond 2StepOnly + msgA-RO-FDM-r16 ENUMERATED {one, two, four, eight} OPTIONAL, -- Cond 2StepOnly + msgA-RO-FrequencyStart-r16 INTEGER (0..maxNrofPhysicalResourceBlocks-1) OPTIONAL, -- Cond 2StepOnly + msgA-ZeroCorrelationZoneConfig-r16 INTEGER (0..15) OPTIONAL, -- Cond 2StepOnly + msgA-PreamblePowerRampingStep-r16 ENUMERATED {dB0, dB2, dB4, dB6} OPTIONAL, -- Cond 2StepOnlyNoCFRA + msgA-PreambleReceivedTargetPower-r16 INTEGER (-202..-60) OPTIONAL, -- Cond 2StepOnlyNoCFRA + msgB-ResponseWindow-r16 ENUMERATED {sl1, sl2, sl4, sl8, sl10, sl20, sl40, sl80, sl160, sl320} + OPTIONAL, -- Cond NoCFRA + preambleTransMax-r16 ENUMERATED {n3, n4, n5, n6, n7, n8, n10, n20, n50, n100, n200} OPTIONAL, -- Cond 2StepOnlyNoCFRA + ... +} + +-- TAG-RACH-CONFIGGENERICTWOSTEPRA-STOP +-- TAG-RA-PRIORITIZATION-START + +RA-Prioritization ::= SEQUENCE { + powerRampingStepHighPriority ENUMERATED {dB0, dB2, dB4, dB6}, + scalingFactorBI ENUMERATED {zero, dot25, dot5, dot75} OPTIONAL, -- Need R + ... +} + +-- TAG-RA-PRIORITIZATION-STOP +-- TAG-RADIOBEARERCONFIG-START + +RadioBearerConfig ::= SEQUENCE { + srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn + srb3-ToRelease ENUMERATED{true} OPTIONAL, -- Need N + drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toNR + drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need N + securityConfig SecurityConfig OPTIONAL, -- Need M + ... +} + +SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod +SRB-ToAddMod ::= SEQUENCE { + srb-Identity SRB-Identity, + reestablishPDCP ENUMERATED{true} OPTIONAL, -- Need N + discardOnPDCP ENUMERATED{true} OPTIONAL, -- Need N + pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP + ... +} + +DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod + +DRB-ToAddMod ::= SEQUENCE { + cnAssociation CHOICE { + eps-BearerIdentity INTEGER (0..15), + sdap-Config SDAP-Config + } OPTIONAL, -- Cond DRBSetup + drb-Identity DRB-Identity, + reestablishPDCP ENUMERATED{true} OPTIONAL, -- Need N + recoverPDCP ENUMERATED{true} OPTIONAL, -- Need N + pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP + ..., + [[ + daps-Config-r16 ENUMERATED{true} OPTIONAL --Need N + ]] +} +DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity + +SecurityConfig ::= SEQUENCE { + securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Cond RBTermChange1 + keyToUse ENUMERATED{master, secondary} OPTIONAL, -- Cond RBTermChange + ... +} + +-- TAG-RADIOBEARERCONFIG-STOP +-- TAG-RADIOLINKMONITORINGCONFIG-START + +RadioLinkMonitoringConfig ::= SEQUENCE { + failureDetectionResourcesToAddModList SEQUENCE (SIZE(1..maxNrofFailureDetectionResources)) OF RadioLinkMonitoringRS + OPTIONAL, -- Need N + failureDetectionResourcesToReleaseList SEQUENCE (SIZE(1..maxNrofFailureDetectionResources)) OF RadioLinkMonitoringRS-Id + OPTIONAL, -- Need N + beamFailureInstanceMaxCount ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10} OPTIONAL, -- Need R + beamFailureDetectionTimer ENUMERATED {pbfd1, pbfd2, pbfd3, pbfd4, pbfd5, pbfd6, pbfd8, pbfd10} OPTIONAL, -- Need R + ... +} + +RadioLinkMonitoringRS ::= SEQUENCE { + radioLinkMonitoringRS-Id RadioLinkMonitoringRS-Id, + purpose ENUMERATED {beamFailure, rlf, both}, + detectionResource CHOICE { + ssb-Index SSB-Index, + csi-RS-Index NZP-CSI-RS-ResourceId + }, + ... +} + +-- TAG-RADIOLINKMONITORINGCONFIG-STOP +-- TAG-RADIOLINKMONITORINGRS-ID-START + +RadioLinkMonitoringRS-Id ::= INTEGER (0..maxNrofFailureDetectionResources-1) + +-- TAG-RADIOLINKMONITORINGRS-ID-STOP +-- TAG-RAN-AREACODE-START + +RAN-AreaCode ::= INTEGER (0..255) + +-- TAG-RAN-AREACODE-STOP +-- TAG-RATEMATCHPATTERN-START + +RateMatchPattern ::= SEQUENCE { + rateMatchPatternId RateMatchPatternId, + + patternType CHOICE { + bitmaps SEQUENCE { + resourceBlocks BIT STRING (SIZE (275)), + symbolsInResourceBlock CHOICE { + oneSlot BIT STRING (SIZE (14)), + twoSlots BIT STRING (SIZE (28)) + }, + periodicityAndPattern CHOICE { + n2 BIT STRING (SIZE (2)), + n4 BIT STRING (SIZE (4)), + n5 BIT STRING (SIZE (5)), + n8 BIT STRING (SIZE (8)), + n10 BIT STRING (SIZE (10)), + n20 BIT STRING (SIZE (20)), + n40 BIT STRING (SIZE (40)) + } OPTIONAL, -- Need S + ... + }, + controlResourceSet ControlResourceSetId + }, + subcarrierSpacing SubcarrierSpacing OPTIONAL, -- Cond CellLevel + dummy ENUMERATED { dynamic, semiStatic }, + ..., + [[ + controlResourceSet-r16 ControlResourceSetId-r16 OPTIONAL -- Need R + ]] + +} + +-- TAG-RATEMATCHPATTERN-STOP +-- TAG-RATEMATCHPATTERNID-START + +RateMatchPatternId ::= INTEGER (0..maxNrofRateMatchPatterns-1) + +-- TAG-RATEMATCHPATTERNID-STOP +-- TAG-RATEMATCHPATTERNLTE-CRS-START + +RateMatchPatternLTE-CRS ::= SEQUENCE { + carrierFreqDL INTEGER (0..16383), + carrierBandwidthDL ENUMERATED {n6, n15, n25, n50, n75, n100, spare2, spare1}, + mbsfn-SubframeConfigList EUTRA-MBSFN-SubframeConfigList OPTIONAL, -- Need M + nrofCRS-Ports ENUMERATED {n1, n2, n4}, + v-Shift ENUMERATED {n0, n1, n2, n3, n4, n5} +} + +LTE-CRS-PatternList-r16 ::= SEQUENCE (SIZE (1..maxLTE-CRS-Patterns-r16)) OF RateMatchPatternLTE-CRS + +-- TAG-RATEMATCHPATTERNLTE-CRS-STOP +-- TAG-REFERENCETIMEINFO-START + +ReferenceTimeInfo-r16 ::= SEQUENCE { + time-r16 ReferenceTime-r16, + uncertainty-r16 INTEGER (0..32767) OPTIONAL, -- Need S + timeInfoType-r16 ENUMERATED {localClock} OPTIONAL, -- Need S + referenceSFN-r16 INTEGER (0..1023) OPTIONAL -- Cond RefTime +} + +ReferenceTime-r16 ::= SEQUENCE { + refDays-r16 INTEGER (0..72999), + refSeconds-r16 INTEGER (0..86399), + refMilliSeconds-r16 INTEGER (0..999), + refTenNanoSeconds-r16 INTEGER (0..99999) +} + +-- TAG-REFERENCETIMEINFO-STOP +-- TAG-REJECTWAITTIME-START + +RejectWaitTime ::= INTEGER (1..16) + +-- TAG-REJECTWAITTIME-STOP +-- TAG-REPETITIONSCHEMECONFIG-START + +RepetitionSchemeConfig-r16 ::= CHOICE { + fdm-TDM-r16 SetupRelease { FDM-TDM-r16 }, + slotBased-r16 SetupRelease { SlotBased-r16 } +} + +FDM-TDM-r16 ::= SEQUENCE { + repetitionScheme-r16 ENUMERATED {fdmSchemeA, fdmSchemeB,tdmSchemeA }, + startingSymbolOffsetK-r16 INTEGER (0..7) OPTIONAL -- Need R +} + +SlotBased-r16 ::= SEQUENCE { + tciMapping-r16 ENUMERATED {cyclicMapping, sequenticalMapping}, + sequenceOffsetforRV-r16 INTEGER (1..3) +} + +-- TAG-REPETITIONSCHEMECONFIG-STOP +-- TAG-REPORTCONFIGID-START + +ReportConfigId ::= INTEGER (1..maxReportConfigId) + +-- TAG-REPORTCONFIGID-STOP +-- TAG-REPORTCONFIGINTERRAT-START + +ReportConfigInterRAT ::= SEQUENCE { + reportType CHOICE { + periodical PeriodicalReportConfigInterRAT, + eventTriggered EventTriggerConfigInterRAT, + reportCGI ReportCGI-EUTRA, + ..., + reportSFTD ReportSFTD-EUTRA + } +} + +ReportCGI-EUTRA ::= SEQUENCE { + cellForWhichToReportCGI EUTRA-PhysCellId, + ..., + [[ + useAutonomousGaps-r16 ENUMERATED {setup} OPTIONAL -- Need R + ]] +} + +ReportSFTD-EUTRA ::= SEQUENCE { + reportSFTD-Meas BOOLEAN, + reportRSRP BOOLEAN, + ... +} + +EventTriggerConfigInterRAT ::= SEQUENCE { + eventId CHOICE { + eventB1 SEQUENCE { + b1-ThresholdEUTRA MeasTriggerQuantityEUTRA, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger, + ... + }, + eventB2 SEQUENCE { + b2-Threshold1 MeasTriggerQuantity, + b2-Threshold2EUTRA MeasTriggerQuantityEUTRA, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger, + ... + }, + ..., + [[ + eventB1-UTRA-FDD-r16 SEQUENCE { + b1-ThresholdUTRA-FDD-r16 MeasTriggerQuantityUTRA-FDD-r16, + reportOnLeave-r16 BOOLEAN, + hysteresis-r16 Hysteresis, + timeToTrigger-r16 TimeToTrigger, + ... + }, + eventB2-UTRA-FDD-r16 SEQUENCE { + b2-Threshold1-r16 MeasTriggerQuantity, + b2-Threshold2UTRA-FDD-r16 MeasTriggerQuantityUTRA-FDD-r16, + reportOnLeave-r16 BOOLEAN, + hysteresis-r16 Hysteresis, + timeToTrigger-r16 TimeToTrigger, + ... + } + ]] + }, + rsType NR-RS-Type, + + reportInterval ReportInterval, + reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + reportQuantity MeasReportQuantity, + maxReportCells INTEGER (1..maxCellReport), + ..., + [[ + reportQuantityUTRA-FDD-r16 MeasReportQuantityUTRA-FDD-r16 OPTIONAL -- Need R + ]] + + +} + +PeriodicalReportConfigInterRAT ::= SEQUENCE { + reportInterval ReportInterval, + reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + reportQuantity MeasReportQuantity, + maxReportCells INTEGER (1..maxCellReport), + ..., + [[ + reportQuantityUTRA-FDD-r16 MeasReportQuantityUTRA-FDD-r16 OPTIONAL -- Need R + ]] +} + +MeasTriggerQuantityUTRA-FDD-r16 ::= CHOICE{ + utra-FDD-RSCP-r16 INTEGER (-5..91), + utra-FDD-EcN0-r16 INTEGER (0..49) +} + +MeasReportQuantityUTRA-FDD-r16 ::= SEQUENCE { + cpich-RSCP BOOLEAN, + cpich-EcN0 BOOLEAN +} + +-- TAG-REPORTCONFIGINTERRAT-STOP +-- TAG-REPORTCONFIGNR-START + +ReportConfigNR ::= SEQUENCE { + reportType CHOICE { + periodical PeriodicalReportConfig, + eventTriggered EventTriggerConfig, + ..., + reportCGI ReportCGI, + reportSFTD ReportSFTD-NR, + condTriggerConfig-r16 CondTriggerConfig-r16, + cli-Periodical-r16 CLI-PeriodicalReportConfig-r16, + cli-EventTriggered-r16 CLI-EventTriggerConfig-r16 + } +} + +ReportCGI ::= SEQUENCE { + cellForWhichToReportCGI PhysCellId, + ..., + [[ + useAutonomousGaps-r16 ENUMERATED {setup} OPTIONAL -- Need R + ]] + +} + +ReportSFTD-NR ::= SEQUENCE { + reportSFTD-Meas BOOLEAN, + reportRSRP BOOLEAN, + ..., + [[ + reportSFTD-NeighMeas ENUMERATED {true} OPTIONAL, -- Need R + drx-SFTD-NeighMeas ENUMERATED {true} OPTIONAL, -- Need R + cellsForWhichToReportSFTD SEQUENCE (SIZE (1..maxCellSFTD)) OF PhysCellId OPTIONAL -- Need R + ]] +} + +CondTriggerConfig-r16 ::= SEQUENCE { + condEventId CHOICE { + condEventA3 SEQUENCE { + a3-Offset MeasTriggerQuantityOffset, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + condEventA5 SEQUENCE { + a5-Threshold1 MeasTriggerQuantity, + a5-Threshold2 MeasTriggerQuantity, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + ... + }, + rsType-r16 NR-RS-Type, + ... +} + +EventTriggerConfig::= SEQUENCE { + eventId CHOICE { + eventA1 SEQUENCE { + a1-Threshold MeasTriggerQuantity, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + eventA2 SEQUENCE { + a2-Threshold MeasTriggerQuantity, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger + }, + eventA3 SEQUENCE { + a3-Offset MeasTriggerQuantityOffset, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger, + useWhiteCellList BOOLEAN + }, + eventA4 SEQUENCE { + a4-Threshold MeasTriggerQuantity, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger, + useWhiteCellList BOOLEAN + }, + eventA5 SEQUENCE { + a5-Threshold1 MeasTriggerQuantity, + a5-Threshold2 MeasTriggerQuantity, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger, + useWhiteCellList BOOLEAN + }, + eventA6 SEQUENCE { + a6-Offset MeasTriggerQuantityOffset, + reportOnLeave BOOLEAN, + hysteresis Hysteresis, + timeToTrigger TimeToTrigger, + useWhiteCellList BOOLEAN + }, + ... + }, + + rsType NR-RS-Type, + + reportInterval ReportInterval, + reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + + reportQuantityCell MeasReportQuantity, + maxReportCells INTEGER (1..maxCellReport), + + reportQuantityRS-Indexes MeasReportQuantity OPTIONAL, -- Need R + maxNrofRS-IndexesToReport INTEGER (1..maxNrofIndexesToReport) OPTIONAL, -- Need R + includeBeamMeasurements BOOLEAN, + reportAddNeighMeas ENUMERATED {setup} OPTIONAL, -- Need R + ..., + [[ + measRSSI-ReportConfig-r16 MeasRSSI-ReportConfig-r16 OPTIONAL, -- Need R + useT312-r16 BOOLEAN OPTIONAL, -- Need M + includeCommonLocationInfo-r16 ENUMERATED {true} OPTIONAL, -- Need R + includeBT-Meas-r16 SetupRelease {BT-NameList-r16} OPTIONAL, -- Need M + includeWLAN-Meas-r16 SetupRelease {WLAN-NameList-r16} OPTIONAL, -- Need M + includeSensor-Meas-r16 SetupRelease {Sensor-NameList-r16} OPTIONAL -- Need M + ]] +} + +PeriodicalReportConfig ::= SEQUENCE { + rsType NR-RS-Type, + + reportInterval ReportInterval, + reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + + reportQuantityCell MeasReportQuantity, + maxReportCells INTEGER (1..maxCellReport), + + reportQuantityRS-Indexes MeasReportQuantity OPTIONAL, -- Need R + maxNrofRS-IndexesToReport INTEGER (1..maxNrofIndexesToReport) OPTIONAL, -- Need R + includeBeamMeasurements BOOLEAN, + useWhiteCellList BOOLEAN, + ..., + [[ + measRSSI-ReportConfig-r16 MeasRSSI-ReportConfig-r16 OPTIONAL, -- Need R + includeCommonLocationInfo-r16 ENUMERATED {true} OPTIONAL, -- Need R + includeBT-Meas-r16 SetupRelease {BT-NameList-r16} OPTIONAL, -- Need M + includeWLAN-Meas-r16 SetupRelease {WLAN-NameList-r16} OPTIONAL, -- Need M + includeSensor-Meas-r16 SetupRelease {Sensor-NameList-r16} OPTIONAL, -- Need M + ul-DelayValueConfig-r16 SetupRelease { UL-DelayValueConfig-r16 } OPTIONAL, -- Need M + reportAddNeighMeas-r16 ENUMERATED {setup} OPTIONAL -- Need R + ]] + +} + +NR-RS-Type ::= ENUMERATED {ssb, csi-rs} + +MeasTriggerQuantity ::= CHOICE { + rsrp RSRP-Range, + rsrq RSRQ-Range, + sinr SINR-Range +} + +MeasTriggerQuantityOffset ::= CHOICE { + rsrp INTEGER (-30..30), + rsrq INTEGER (-30..30), + sinr INTEGER (-30..30) +} + + +MeasReportQuantity ::= SEQUENCE { + rsrp BOOLEAN, + rsrq BOOLEAN, + sinr BOOLEAN +} + +MeasRSSI-ReportConfig-r16 ::= SEQUENCE { + channelOccupancyThreshold-r16 RSSI-Range-r16 OPTIONAL -- Need R +} + +CLI-EventTriggerConfig-r16 ::= SEQUENCE { + eventId-r16 CHOICE { + eventI1-r16 SEQUENCE { + i1-Threshold-r16 MeasTriggerQuantityCLI-r16, + reportOnLeave-r16 BOOLEAN, + hysteresis-r16 Hysteresis, + timeToTrigger-r16 TimeToTrigger + }, + ... + }, + reportInterval-r16 ReportInterval, + reportAmount-r16 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + maxReportCLI-r16 INTEGER (1..maxCLI-Report-r16), + ... +} + +CLI-PeriodicalReportConfig-r16 ::= SEQUENCE { + reportInterval-r16 ReportInterval, + reportAmount-r16 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + reportQuantityCLI-r16 MeasReportQuantityCLI-r16, + maxReportCLI-r16 INTEGER (1..maxCLI-Report-r16), + ... +} + +MeasTriggerQuantityCLI-r16 ::= CHOICE { + srs-RSRP-r16 SRS-RSRP-Range-r16, + cli-RSSI-r16 CLI-RSSI-Range-r16 +} + +MeasReportQuantityCLI-r16 ::= ENUMERATED {srs-rsrp, cli-rssi} + +-- TAG-REPORTCONFIGNR-STOP +-- TAG-REPORTCONFIGNR-SL-START + +ReportConfigNR-SL-r16 ::= SEQUENCE { + reportType-r16 CHOICE { + periodical-r16 PeriodicalReportConfigNR-SL-r16, + eventTriggered-r16 EventTriggerConfigNR-SL-r16 + } +} + +EventTriggerConfigNR-SL-r16::= SEQUENCE { + eventId-r16 CHOICE { + eventC1 SEQUENCE { + c1-Threshold-r16 SL-CBR-r16, + hysteresis-r16 Hysteresis, + timeToTrigger-r16 TimeToTrigger + }, + eventC2-r16 SEQUENCE { + c2-Threshold-r16 SL-CBR-r16, + hysteresis-r16 Hysteresis, + timeToTrigger-r16 TimeToTrigger + }, + ... + }, + reportInterval-r16 ReportInterval, + reportAmount-r16 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + reportQuantity-r16 MeasReportQuantity-r16, + ... +} + +PeriodicalReportConfigNR-SL-r16 ::= SEQUENCE { + reportInterval-r16 ReportInterval, + reportAmount-r16 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + reportQuantity-r16 MeasReportQuantity-r16, + ... +} + +MeasReportQuantity-r16 ::= SEQUENCE { + cbr-r16 BOOLEAN, + ... +} + +-- TAG-REPORTCONFIGNR-SL-STOP +-- TAG-REPORTCONFIGTOADDMODLIST-START + +ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod + +ReportConfigToAddMod ::= SEQUENCE { + reportConfigId ReportConfigId, + reportConfig CHOICE { + reportConfigNR ReportConfigNR, + ..., + reportConfigInterRAT ReportConfigInterRAT, + reportConfigNR-SL-r16 ReportConfigNR-SL-r16 + } +} + +-- TAG-REPORTCONFIGTOADDMODLIST-STOP +-- TAG-REPORTINTERVAL-START + +ReportInterval ::= ENUMERATED {ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, ms20480, ms40960, + min1,min6, min12, min30 } + +-- TAG-REPORTINTERVAL-STOP +-- TAG-RESELECTIONTHRESHOLD-START + +ReselectionThreshold ::= INTEGER (0..31) + +-- TAG-RESELECTIONTHRESHOLD-STOP +-- TAG-RESELECTIONTHRESHOLDQ-START + +ReselectionThresholdQ ::= INTEGER (0..31) + +-- TAG-RESELECTIONTHRESHOLDQ-STOP +-- TAG-RESUMECAUSE-START + +ResumeCause ::= ENUMERATED {emergency, highPriorityAccess, mt-Access, mo-Signalling, + mo-Data, mo-VoiceCall, mo-VideoCall, mo-SMS, rna-Update, mps-PriorityAccess, + mcs-PriorityAccess, spare1, spare2, spare3, spare4, spare5 } + +-- TAG-RESUMECAUSE-STOP +-- TAG-RLC-BEARERCONFIG-START + +RLC-BearerConfig ::= SEQUENCE { + logicalChannelIdentity LogicalChannelIdentity, + servedRadioBearer CHOICE { + srb-Identity SRB-Identity, + drb-Identity DRB-Identity + } OPTIONAL, -- Cond LCH-SetupOnly + reestablishRLC ENUMERATED {true} OPTIONAL, -- Need N + rlc-Config RLC-Config OPTIONAL, -- Cond LCH-Setup + mac-LogicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond LCH-Setup + ..., + [[ + rlc-Config-v1610 RLC-Config-v1610 OPTIONAL -- Need R + ]] +} + +-- TAG-RLC-BEARERCONFIG-STOP +-- TAG-RLC-CONFIG-START + +RLC-Config ::= CHOICE { + am SEQUENCE { + ul-AM-RLC UL-AM-RLC, + dl-AM-RLC DL-AM-RLC + }, + um-Bi-Directional SEQUENCE { + ul-UM-RLC UL-UM-RLC, + dl-UM-RLC DL-UM-RLC + }, + um-Uni-Directional-UL SEQUENCE { + ul-UM-RLC UL-UM-RLC + }, + um-Uni-Directional-DL SEQUENCE { + dl-UM-RLC DL-UM-RLC + }, + ... +} + +UL-AM-RLC ::= SEQUENCE { + sn-FieldLength SN-FieldLengthAM OPTIONAL, -- Cond Reestab + t-PollRetransmit T-PollRetransmit, + pollPDU PollPDU, + pollByte PollByte, + maxRetxThreshold ENUMERATED { t1, t2, t3, t4, t6, t8, t16, t32 } +} + +DL-AM-RLC ::= SEQUENCE { + sn-FieldLength SN-FieldLengthAM OPTIONAL, -- Cond Reestab + t-Reassembly T-Reassembly, + t-StatusProhibit T-StatusProhibit +} + +UL-UM-RLC ::= SEQUENCE { + sn-FieldLength SN-FieldLengthUM OPTIONAL -- Cond Reestab +} + +DL-UM-RLC ::= SEQUENCE { + sn-FieldLength SN-FieldLengthUM OPTIONAL, -- Cond Reestab + t-Reassembly T-Reassembly +} + +T-PollRetransmit ::= ENUMERATED { + ms5, ms10, ms15, ms20, ms25, ms30, ms35, + ms40, ms45, ms50, ms55, ms60, ms65, ms70, + ms75, ms80, ms85, ms90, ms95, ms100, ms105, + ms110, ms115, ms120, ms125, ms130, ms135, + ms140, ms145, ms150, ms155, ms160, ms165, + ms170, ms175, ms180, ms185, ms190, ms195, + ms200, ms205, ms210, ms215, ms220, ms225, + ms230, ms235, ms240, ms245, ms250, ms300, + ms350, ms400, ms450, ms500, ms800, ms1000, + ms2000, ms4000, ms1-v1610, ms2-v1610, ms3-v1610, + ms4-v1610, spare1} + + +PollPDU ::= ENUMERATED { + p4, p8, p16, p32, p64, p128, p256, p512, p1024, p2048, p4096, p6144, p8192, p12288, p16384,p20480, + p24576, p28672, p32768, p40960, p49152, p57344, p65536, infinity, spare8, spare7, spare6, spare5, spare4, + spare3, spare2, spare1} + +PollByte ::= ENUMERATED { + kB1, kB2, kB5, kB8, kB10, kB15, kB25, kB50, kB75, + kB100, kB125, kB250, kB375, kB500, kB750, kB1000, + kB1250, kB1500, kB2000, kB3000, kB4000, kB4500, + kB5000, kB5500, kB6000, kB6500, kB7000, kB7500, + mB8, mB9, mB10, mB11, mB12, mB13, mB14, mB15, + mB16, mB17, mB18, mB20, mB25, mB30, mB40, infinity, + spare20, spare19, spare18, spare17, spare16, + spare15, spare14, spare13, spare12, spare11, + spare10, spare9, spare8, spare7, spare6, spare5, + spare4, spare3, spare2, spare1} + +T-Reassembly ::= ENUMERATED { + ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, + ms40, ms45, ms50, ms55, ms60, ms65, ms70, + ms75, ms80, ms85, ms90, ms95, ms100, ms110, + ms120, ms130, ms140, ms150, ms160, ms170, + ms180, ms190, ms200, spare1} + +T-StatusProhibit ::= ENUMERATED { + ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, + ms40, ms45, ms50, ms55, ms60, ms65, ms70, + ms75, ms80, ms85, ms90, ms95, ms100, ms105, + ms110, ms115, ms120, ms125, ms130, ms135, + ms140, ms145, ms150, ms155, ms160, ms165, + ms170, ms175, ms180, ms185, ms190, ms195, + ms200, ms205, ms210, ms215, ms220, ms225, + ms230, ms235, ms240, ms245, ms250, ms300, + ms350, ms400, ms450, ms500, ms800, ms1000, + ms1200, ms1600, ms2000, ms2400, spare2, spare1} + +SN-FieldLengthUM ::= ENUMERATED {size6, size12} +SN-FieldLengthAM ::= ENUMERATED {size12, size18} + +RLC-Config-v1610 ::= SEQUENCE { + dl-AM-RLC-v1610 DL-AM-RLC-v1610 +} + +DL-AM-RLC-v1610 ::= SEQUENCE { + t-StatusProhibit-v1610 T-StatusProhibit-v1610 OPTIONAL, -- Need N + ... +} + +T-StatusProhibit-v1610 ::= ENUMERATED { ms1, ms2, ms3, ms4, spare4, spare3, spare2, spare1} + +-- TAG-RLC-CONFIG-STOP +-- TAG-RLF-TIMERSANDCONSTANTS-START + +RLF-TimersAndConstants ::= SEQUENCE { + t310 ENUMERATED {ms0, ms50, ms100, ms200, ms500, ms1000, ms2000, ms4000, ms6000}, + n310 ENUMERATED {n1, n2, n3, n4, n6, n8, n10, n20}, + n311 ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10}, + ..., + [[ + t311 ENUMERATED {ms1000, ms3000, ms5000, ms10000, ms15000, ms20000, ms30000} + ]] +} + +-- TAG-RLF-TIMERSANDCONSTANTS-STOP +-- TAG-RNTI-VALUE-START + +RNTI-Value ::= INTEGER (0..65535) + +-- TAG-RNTI-VALUE-STOP +-- TAG-RSRP-RANGE-START + +RSRP-Range ::= INTEGER(0..127) + +-- TAG-RSRP-RANGE-STOP +-- TAG-RSRQ-RANGE-START + +RSRQ-Range ::= INTEGER(0..127) + +-- TAG-RSRQ-RANGE-STOP +-- TAG-RSSI-RANGE-START + +RSSI-Range-r16 ::= INTEGER(0..76) + +-- TAG-RSSI-RANGE-STOP +-- TAG-SCELLINDEX-START + +SCellIndex ::= INTEGER (1..31) + +-- TAG-SCELLINDEX-STOP +-- TAG-SCHEDULINGREQUESTCONFIG-START + +SchedulingRequestConfig ::= SEQUENCE { + schedulingRequestToAddModList SEQUENCE (SIZE (1..maxNrofSR-ConfigPerCellGroup)) OF SchedulingRequestToAddMod + OPTIONAL, -- Need N + schedulingRequestToReleaseList SEQUENCE (SIZE (1..maxNrofSR-ConfigPerCellGroup)) OF SchedulingRequestId + OPTIONAL -- Need N +} + +SchedulingRequestToAddMod ::= SEQUENCE { + schedulingRequestId SchedulingRequestId, + sr-ProhibitTimer ENUMERATED {ms1, ms2, ms4, ms8, ms16, ms32, ms64, ms128} OPTIONAL, -- Need S + sr-TransMax ENUMERATED { n4, n8, n16, n32, n64, spare3, spare2, spare1} +} + + + +-- TAG-SCHEDULINGREQUESTCONFIG-STOP +-- TAG-SCHEDULINGREQUESTID-START + +SchedulingRequestId ::= INTEGER (0..7) + +-- TAG-SCHEDULINGREQUESTID-STOP +-- TAG-SCHEDULINGREQUESTRESOURCECONFIG-START + +SchedulingRequestResourceConfig ::= SEQUENCE { + schedulingRequestResourceId SchedulingRequestResourceId, + schedulingRequestID SchedulingRequestId, + periodicityAndOffset CHOICE { + sym2 NULL, + sym6or7 NULL, + sl1 NULL, -- Recurs in every slot + sl2 INTEGER (0..1), + sl4 INTEGER (0..3), + sl5 INTEGER (0..4), + sl8 INTEGER (0..7), + sl10 INTEGER (0..9), + sl16 INTEGER (0..15), + sl20 INTEGER (0..19), + sl40 INTEGER (0..39), + sl80 INTEGER (0..79), + sl160 INTEGER (0..159), + sl320 INTEGER (0..319), + sl640 INTEGER (0..639) + } OPTIONAL, -- Need M + resource PUCCH-ResourceId OPTIONAL -- Need M +} + +SchedulingRequestResourceConfig-v1610 ::= SEQUENCE { + phy-PriorityIndex-r16 ENUMERATED {p0, p1} OPTIONAL, -- Need M + ... +} + +-- TAG-SCHEDULINGREQUESTRESOURCECONFIG-STOP +-- TAG-SCHEDULINGREQUESTRESOURCEID-START + +SchedulingRequestResourceId ::= INTEGER (1..maxNrofSR-Resources) + +-- TAG-SCHEDULINGREQUESTRESOURCEID-STOP +-- TAG-SCRAMBLINGID-START + +ScramblingId ::= INTEGER(0..1023) + +-- TAG-SCRAMBLINGID-STOP +-- TAG-SCS-SPECIFICCARRIER-START + +SCS-SpecificCarrier ::= SEQUENCE { + offsetToCarrier INTEGER (0..2199), + subcarrierSpacing SubcarrierSpacing, + carrierBandwidth INTEGER (1..maxNrofPhysicalResourceBlocks), + ..., + [[ + txDirectCurrentLocation INTEGER (0..4095) OPTIONAL -- Need S + ]] +} + +-- TAG-SCS-SPECIFICCARRIER-STOP +-- TAG-SDAP-CONFIG-START + +SDAP-Config ::= SEQUENCE { + pdu-Session PDU-SessionID, + sdap-HeaderDL ENUMERATED {present, absent}, + sdap-HeaderUL ENUMERATED {present, absent}, + defaultDRB BOOLEAN, + mappedQoS-FlowsToAdd SEQUENCE (SIZE (1..maxNrofQFIs)) OF QFI OPTIONAL, -- Need N + mappedQoS-FlowsToRelease SEQUENCE (SIZE (1..maxNrofQFIs)) OF QFI OPTIONAL, -- Need N + ... +} + +QFI ::= INTEGER (0..maxQFI) + +PDU-SessionID ::= INTEGER (0..255) + +-- TAG-SDAP-CONFIG-STOP +-- TAG-SEARCHSPACE-START + +SearchSpace ::= SEQUENCE { + searchSpaceId SearchSpaceId, + controlResourceSetId ControlResourceSetId OPTIONAL, -- Cond SetupOnly + monitoringSlotPeriodicityAndOffset CHOICE { + sl1 NULL, + sl2 INTEGER (0..1), + sl4 INTEGER (0..3), + sl5 INTEGER (0..4), + sl8 INTEGER (0..7), + sl10 INTEGER (0..9), + sl16 INTEGER (0..15), + sl20 INTEGER (0..19), + sl40 INTEGER (0..39), + sl80 INTEGER (0..79), + sl160 INTEGER (0..159), + sl320 INTEGER (0..319), + sl640 INTEGER (0..639), + sl1280 INTEGER (0..1279), + sl2560 INTEGER (0..2559) + } OPTIONAL, -- Cond Setup + duration INTEGER (2..2559) OPTIONAL, -- Need R + monitoringSymbolsWithinSlot BIT STRING (SIZE (14)) OPTIONAL, -- Cond Setup + nrofCandidates SEQUENCE { + aggregationLevel1 ENUMERATED {n0, n1, n2, n3, n4, n5, n6, n8}, + aggregationLevel2 ENUMERATED {n0, n1, n2, n3, n4, n5, n6, n8}, + aggregationLevel4 ENUMERATED {n0, n1, n2, n3, n4, n5, n6, n8}, + aggregationLevel8 ENUMERATED {n0, n1, n2, n3, n4, n5, n6, n8}, + aggregationLevel16 ENUMERATED {n0, n1, n2, n3, n4, n5, n6, n8} + } OPTIONAL, -- Cond Setup + searchSpaceType CHOICE { + common SEQUENCE { + dci-Format0-0-AndFormat1-0 SEQUENCE { + ... + } OPTIONAL, -- Need R + dci-Format2-0 SEQUENCE { + nrofCandidates-SFI SEQUENCE { + aggregationLevel1 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel2 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel4 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel8 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel16 ENUMERATED {n1, n2} OPTIONAL -- Need R + }, + ... + } OPTIONAL, -- Need R + dci-Format2-1 SEQUENCE { + ... + } OPTIONAL, -- Need R + dci-Format2-2 SEQUENCE { + ... + } OPTIONAL, -- Need R + dci-Format2-3 SEQUENCE { + dummy1 ENUMERATED {sl1, sl2, sl4, sl5, sl8, sl10, sl16, sl20} OPTIONAL, -- Cond Setup + dummy2 ENUMERATED {n1, n2}, + ... + } OPTIONAL -- Need R + }, + ue-Specific SEQUENCE { + dci-Formats ENUMERATED {formats0-0-And-1-0, formats0-1-And-1-1}, + ..., + [[ + dci-Formats-MT-r16 ENUMERATED {formats2-5} OPTIONAL, -- Need R + dci-FormatsSL-r16 ENUMERATED {formats0-0-And-1-0, formats0-1-And-1-1, formats3-0, formats3-1, + formats3-0-And-3-1} OPTIONAL, -- Need R + dci-FormatsExt-r16 ENUMERATED {formats0-2-And-1-2, formats0-1-And-1-1And-0-2-And-1-2} + OPTIONAL -- Need R + ]] + } + } OPTIONAL -- Cond Setup2 +} + +SearchSpaceExt-r16 ::= SEQUENCE { + controlResourceSetId-r16 ControlResourceSetId-r16 OPTIONAL, -- Cond SetupOnly2 + searchSpaceType-r16 SEQUENCE { + common-r16 SEQUENCE { + dci-Format2-4-r16 SEQUENCE { + nrofCandidates-CI-r16 SEQUENCE { + aggregationLevel1-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel2-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel4-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel8-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel16-r16 ENUMERATED {n1, n2} OPTIONAL -- Need R + }, + ... + } OPTIONAL, -- Need R + dci-Format2-5-r16 SEQUENCE { + nrofCandidates-IAB-r16 SEQUENCE { + aggregationLevel1-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel2-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel4-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel8-r16 ENUMERATED {n1, n2} OPTIONAL, -- Need R + aggregationLevel16-r16 ENUMERATED {n1, n2} OPTIONAL -- Need R + }, + ... + } OPTIONAL, -- Need R + dci-Format2-6-r16 SEQUENCE { + ... + } OPTIONAL, -- Need R + ... + } + } OPTIONAL, -- Cond Setup3 + searchSpaceGroupIdList-r16 SEQUENCE (SIZE (1.. 2)) OF INTEGER (0..1) OPTIONAL, -- Need R + freqMonitorLocations-r16 BIT STRING (SIZE (5)) OPTIONAL -- Need R +} + +-- TAG-SEARCHSPACE-STOP +-- TAG-SEARCHSPACEID-START + +SearchSpaceId ::= INTEGER (0..maxNrofSearchSpaces-1) + +-- TAG-SEARCHSPACEID-STOP +-- TAG-SEARCHSPACEZERO-START + +SearchSpaceZero ::= INTEGER (0..15) + +-- TAG-SEARCHSPACEZERO-STOP +-- TAG-SECURITYALGORITHMCONFIG-START + +SecurityAlgorithmConfig ::= SEQUENCE { + cipheringAlgorithm CipheringAlgorithm, + integrityProtAlgorithm IntegrityProtAlgorithm OPTIONAL, -- Need R + ... +} + +IntegrityProtAlgorithm ::= ENUMERATED { + nia0, nia1, nia2, nia3, spare4, spare3, + spare2, spare1, ...} + +CipheringAlgorithm ::= ENUMERATED { + nea0, nea1, nea2, nea3, spare4, spare3, + spare2, spare1, ...} + +-- TAG-SECURITYALGORITHMCONFIG-STOP +-- TAG-SEMISTATICCHANNELACCESSCONFIG-START + +SemiStaticChannelAccessConfig ::= SEQUENCE { + period ENUMERATED {ms1, ms2, ms2dot5, ms4, ms5, ms10} +} + +-- TAG-SEMISTATICCHANNELACCESSCONFIG-STOP +-- TAG-SENSORLOCATIONINFO-START + +Sensor-LocationInfo-r16 ::= SEQUENCE { + sensor-MeasurementInformation-r16 OCTET STRING OPTIONAL, + sensor-MotionInformation-r16 OCTET STRING OPTIONAL, + ... +} + +-- TAG-SENSORLOCATIONINFO-STOP +-- TAG-SERVCELLINDEX-START + +ServCellIndex ::= INTEGER (0..maxNrofServingCells-1) + +-- TAG-SERVCELLINDEX-STOP +-- TAG-SERVINGCELLCONFIG-START + +ServingCellConfig ::= SEQUENCE { + tdd-UL-DL-ConfigurationDedicated TDD-UL-DL-ConfigDedicated OPTIONAL, -- Cond TDD + initialDownlinkBWP BWP-DownlinkDedicated OPTIONAL, -- Need M + downlinkBWP-ToReleaseList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Id OPTIONAL, -- Need N + downlinkBWP-ToAddModList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Downlink OPTIONAL, -- Need N + firstActiveDownlinkBWP-Id BWP-Id OPTIONAL, -- Cond SyncAndCellAdd + bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, + ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, + ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, + spare7, spare6, spare5, spare4, spare3, spare2, spare1 } OPTIONAL, --Need R + defaultDownlinkBWP-Id BWP-Id OPTIONAL, -- Need S + uplinkConfig UplinkConfig OPTIONAL, -- Need M + supplementaryUplink UplinkConfig OPTIONAL, -- Need M + pdcch-ServingCellConfig SetupRelease { PDCCH-ServingCellConfig } OPTIONAL, -- Need M + pdsch-ServingCellConfig SetupRelease { PDSCH-ServingCellConfig } OPTIONAL, -- Need M + csi-MeasConfig SetupRelease { CSI-MeasConfig } OPTIONAL, -- Need M + sCellDeactivationTimer ENUMERATED {ms20, ms40, ms80, ms160, ms200, ms240, + ms320, ms400, ms480, ms520, ms640, ms720, + ms840, ms1280, spare2,spare1} OPTIONAL, -- Cond ServingCellWithoutPUCCH + crossCarrierSchedulingConfig CrossCarrierSchedulingConfig OPTIONAL, -- Need M + tag-Id TAG-Id, + dummy ENUMERATED {enabled} OPTIONAL, -- Need R + pathlossReferenceLinking ENUMERATED {spCell, sCell} OPTIONAL, -- Cond SCellOnly + servingCellMO MeasObjectId OPTIONAL, -- Cond MeasObject + ..., + [[ + lte-CRS-ToMatchAround SetupRelease { RateMatchPatternLTE-CRS } OPTIONAL, -- Need M + rateMatchPatternToAddModList SEQUENCE (SIZE (1..maxNrofRateMatchPatterns)) OF RateMatchPattern OPTIONAL, -- Need N + rateMatchPatternToReleaseList SEQUENCE (SIZE (1..maxNrofRateMatchPatterns)) OF RateMatchPatternId OPTIONAL, -- Need N + downlinkChannelBW-PerSCS-List SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier OPTIONAL -- Need S + ]], + [[ + supplementaryUplinkRelease ENUMERATED {true} OPTIONAL, -- Need N + tdd-UL-DL-ConfigurationDedicated-iab-mt-r16 TDD-UL-DL-ConfigDedicated-IAB-MT-r16 OPTIONAL, -- Cond TDD_IAB + dormantBWP-Config-r16 SetupRelease { DormantBWP-Config-r16 } OPTIONAL, -- Need M + ca-SlotOffset-r16 CHOICE { + refSCS15kHz INTEGER (-2..2), + refSCS30KHz INTEGER (-5..5), + refSCS60KHz INTEGER (-10..10), + refSCS120KHz INTEGER (-20..20) + } OPTIONAL, -- Cond AsyncCA + channelAccessConfig-r16 SetupRelease { ChannelAccessConfig-r16 } OPTIONAL, -- Need M + intraCellGuardBandsUL-r16 IntraCellGuardBands-r16 OPTIONAL, -- Need S + intraCellGuardBandsDL-r16 IntraCellGuardBands-r16 OPTIONAL, -- Need S + csi-RS-ValidationWith-DCI-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + lte-CRS-PatternList1-r16 SetupRelease { LTE-CRS-PatternList-r16 } OPTIONAL, -- Need M + lte-CRS-PatternList2-r16 SetupRelease { LTE-CRS-PatternList-r16 } OPTIONAL, -- Need M + crs-RateMatch-PerCORESETPoolIndex-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + enableTwoDefaultTCIStates-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + enableDefaultTCIStatePerCoresetPoolIndex-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + enableBeamSwitchTiming-r16 ENUMERATED {true} OPTIONAL, -- Need R + cbg-TxDiffTBsProcessingType1-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + cbg-TxDiffTBsProcessingType2-r16 ENUMERATED {enabled} OPTIONAL -- Need R + ]] +} + +UplinkConfig ::= SEQUENCE { + initialUplinkBWP BWP-UplinkDedicated OPTIONAL, -- Need M + uplinkBWP-ToReleaseList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Id OPTIONAL, -- Need N + uplinkBWP-ToAddModList SEQUENCE (SIZE (1..maxNrofBWPs)) OF BWP-Uplink OPTIONAL, -- Need N + firstActiveUplinkBWP-Id BWP-Id OPTIONAL, -- Cond SyncAndCellAdd + pusch-ServingCellConfig SetupRelease { PUSCH-ServingCellConfig } OPTIONAL, -- Need M + carrierSwitching SetupRelease { SRS-CarrierSwitching } OPTIONAL, -- Need M + ..., + [[ + powerBoostPi2BPSK BOOLEAN OPTIONAL, -- Need M + uplinkChannelBW-PerSCS-List SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier OPTIONAL -- Need S + ]], + [[ + enablePLRS-UpdateForPUSCH-SRS-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + enableDefaultBeamPL-ForPUSCH0-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + enableDefaultBeamPL-ForPUCCH-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + enableDefaultBeamPL-ForSRS-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + uplinkTxSwitching-r16 SetupRelease { UplinkTxSwitching-r16 } OPTIONAL -- Need M + ]] +} + +ChannelAccessConfig-r16 ::= SEQUENCE { + maxEnergyDetectionThreshold-r16 INTEGER(-85..-52), + energyDetectionThresholdOffset-r16 INTEGER (-20..-13), + ul-toDL-COT-SharingED-Threshold-r16 INTEGER (-85..-52) OPTIONAL, -- Need R + absenceOfAnyOtherTechnology-r16 ENUMERATED {true} OPTIONAL -- Need R +} + +IntraCellGuardBands-r16 ::= SEQUENCE (SIZE (1..4)) OF GuardBand-r16 + +GuardBand-r16 ::= SEQUENCE { + startCRB-r16 INTEGER (0..274), + nrofCRBs-r16 INTEGER (0..15) +} + +DormancyGroupID-r16 ::= INTEGER (0..4) + +DormantBWP-Config-r16::= SEQUENCE { + dormantBWP-Id-r16 BWP-Id OPTIONAL, -- Need M + withinActiveTimeConfig-r16 SetupRelease { WithinActiveTimeConfig-r16 } OPTIONAL, -- Need M + outsideActiveTimeConfig-r16 SetupRelease { OutsideActiveTimeConfig-r16 } OPTIONAL -- Need M +} + +WithinActiveTimeConfig-r16 ::= SEQUENCE { + firstWithinActiveTimeBWP-Id-r16 BWP-Id OPTIONAL, -- Need M + dormancyGroupWithinActiveTime-r16 DormancyGroupID-r16 OPTIONAL -- Need R +} + +OutsideActiveTimeConfig-r16 ::= SEQUENCE { + firstOutsideActiveTimeBWP-Id-r16 BWP-Id OPTIONAL, -- Need M + dormancyGroupOutsideActiveTime-r16 DormancyGroupID-r16 OPTIONAL -- Need R +} + +UplinkTxSwitching-r16 ::= SEQUENCE { + uplinkTxSwitchingPeriodLocation-r16 BOOLEAN, + uplinkTxSwitchingCarrier-r16 ENUMERATED {carrier1, carrier2} +} + +-- TAG-SERVINGCELLCONFIG-STOP +-- TAG-SERVINGCELLCONFIGCOMMON-START + +ServingCellConfigCommon ::= SEQUENCE { + physCellId PhysCellId OPTIONAL, -- Cond HOAndServCellAdd, + downlinkConfigCommon DownlinkConfigCommon OPTIONAL, -- Cond HOAndServCellAdd + uplinkConfigCommon UplinkConfigCommon OPTIONAL, -- Need M + supplementaryUplinkConfig UplinkConfigCommon OPTIONAL, -- Need S + n-TimingAdvanceOffset ENUMERATED { n0, n25600, n39936 } OPTIONAL, -- Need S + ssb-PositionsInBurst CHOICE { + shortBitmap BIT STRING (SIZE (4)), + mediumBitmap BIT STRING (SIZE (8)), + longBitmap BIT STRING (SIZE (64)) + } OPTIONAL, -- Cond AbsFreqSSB + ssb-periodicityServingCell ENUMERATED { ms5, ms10, ms20, ms40, ms80, ms160, spare2, spare1 } OPTIONAL, -- Need S + dmrs-TypeA-Position ENUMERATED {pos2, pos3}, + lte-CRS-ToMatchAround SetupRelease { RateMatchPatternLTE-CRS } OPTIONAL, -- Need M + rateMatchPatternToAddModList SEQUENCE (SIZE (1..maxNrofRateMatchPatterns)) OF RateMatchPattern OPTIONAL, -- Need N + rateMatchPatternToReleaseList SEQUENCE (SIZE (1..maxNrofRateMatchPatterns)) OF RateMatchPatternId OPTIONAL, -- Need N + ssbSubcarrierSpacing SubcarrierSpacing OPTIONAL, -- Cond HOAndServCellWithSSB + tdd-UL-DL-ConfigurationCommon TDD-UL-DL-ConfigCommon OPTIONAL, -- Cond TDD + ss-PBCH-BlockPower INTEGER (-60..50), + ..., + [[ + channelAccessMode-r16 CHOICE { + dynamic NULL, + semiStatic SemiStaticChannelAccessConfig + } OPTIONAL, -- Cond SharedSpectrum + discoveryBurstWindowLength-r16 ENUMERATED {ms0dot5, ms1, ms2, ms3, ms4, ms5} OPTIONAL, -- Need M + ssb-PositionQCL-r16 SSB-PositionQCL-Relation-r16 OPTIONAL, -- Cond SharedSpectrum + highSpeedConfig-r16 HighSpeedConfig-r16 OPTIONAL -- Need R + ]] +} + +-- TAG-SERVINGCELLCONFIGCOMMON-STOP +-- TAG-SERVINGCELLCONFIGCOMMONSIB-START + +ServingCellConfigCommonSIB ::= SEQUENCE { + downlinkConfigCommon DownlinkConfigCommonSIB, + uplinkConfigCommon UplinkConfigCommonSIB OPTIONAL, -- Need R + supplementaryUplink UplinkConfigCommonSIB OPTIONAL, -- Need R + n-TimingAdvanceOffset ENUMERATED { n0, n25600, n39936 } OPTIONAL, -- Need S + ssb-PositionsInBurst SEQUENCE { + inOneGroup BIT STRING (SIZE (8)), + groupPresence BIT STRING (SIZE (8)) OPTIONAL -- Cond FR2-Only + }, + ssb-PeriodicityServingCell ENUMERATED {ms5, ms10, ms20, ms40, ms80, ms160}, + tdd-UL-DL-ConfigurationCommon TDD-UL-DL-ConfigCommon OPTIONAL, -- Cond TDD + ss-PBCH-BlockPower INTEGER (-60..50), + ..., + [[ + channelAccessMode-r16 CHOICE { + dynamic NULL, + semiStatic SemiStaticChannelAccessConfig + } OPTIONAL, -- Cond SharedSpectrum + discoveryBurstWindowLength-r16 ENUMERATED {ms0dot5, ms1, ms2, ms3, ms4, ms5} OPTIONAL, -- Need R + highSpeedConfig-r16 HighSpeedConfig-r16 OPTIONAL -- Need R + ]] +} + +-- TAG-SERVINGCELLCONFIGCOMMONSIB-STOP +-- TAG-SHORTI-RNTI-VALUE-START + +ShortI-RNTI-Value ::= BIT STRING (SIZE(24)) + +-- TAG-SHORTI-RNTI-VALUE-STOP +-- TAG-SHORTMAC-I-START + +ShortMAC-I ::= BIT STRING (SIZE (16)) + +-- TAG-SHORTMAC-I-STOP +-- TAG-SINR-RANGE-START + +SINR-Range ::= INTEGER(0..127) + +-- TAG-SINR-RANGE-STOP +-- TAG-SI-REQUESTCONFIG-START + +SI-RequestConfig::= SEQUENCE { + rach-OccasionsSI SEQUENCE { + rach-ConfigSI RACH-ConfigGeneric, + ssb-perRACH-Occasion ENUMERATED {oneEighth, oneFourth, oneHalf, one, two, four, eight, sixteen} + } OPTIONAL, -- Need R + si-RequestPeriod ENUMERATED {one, two, four, six, eight, ten, twelve, sixteen} OPTIONAL, -- Need R + si-RequestResources SEQUENCE (SIZE (1..maxSI-Message)) OF SI-RequestResources +} + +SI-RequestResources ::= SEQUENCE { + ra-PreambleStartIndex INTEGER (0..63), + ra-AssociationPeriodIndex INTEGER (0..15) OPTIONAL, -- Need R + ra-ssb-OccasionMaskIndex INTEGER (0..15) OPTIONAL -- Need R +} + +-- TAG-SI-SCHEDULINGINFO-START + +SI-SchedulingInfo ::= SEQUENCE { + schedulingInfoList SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo, + si-WindowLength ENUMERATED {s5, s10, s20, s40, s80, s160, s320, s640, s1280}, + si-RequestConfig SI-RequestConfig OPTIONAL, -- Cond MSG-1 + si-RequestConfigSUL SI-RequestConfig OPTIONAL, -- Cond SUL-MSG-1 + systemInformationAreaID BIT STRING (SIZE (24)) OPTIONAL, -- Need R + ... +} + +SchedulingInfo ::= SEQUENCE { + si-BroadcastStatus ENUMERATED {broadcasting, notBroadcasting}, + si-Periodicity ENUMERATED {rf8, rf16, rf32, rf64, rf128, rf256, rf512}, + sib-MappingInfo SIB-Mapping +} + +SIB-Mapping ::= SEQUENCE (SIZE (1..maxSIB)) OF SIB-TypeInfo + +SIB-TypeInfo ::= SEQUENCE { + type ENUMERATED {sibType2, sibType3, sibType4, sibType5, sibType6, sibType7, sibType8, sibType9, + sibType10-v1610, sibType11-v1610, sibType12-v1610, sibType13-v1610, sibType14-v1610, + spare3, spare2, spare1,... }, + valueTag INTEGER (0..31) OPTIONAL, -- Cond SIB-TYPE + areaScope ENUMERATED {true} OPTIONAL -- Need S +} + +-- TAG-SI-SCHEDULINGINFO-STOP +-- TAG-SKCOUNTER-START + +SK-Counter ::= INTEGER (0..65535) + +-- TAG-SKCOUNTER-STOP +-- TAG-SLOTFORMATCOMBINATIONSPERCELL-START + +SlotFormatCombinationsPerCell ::= SEQUENCE { + servingCellId ServCellIndex, + subcarrierSpacing SubcarrierSpacing, + subcarrierSpacing2 SubcarrierSpacing OPTIONAL, -- Need R + slotFormatCombinations SEQUENCE (SIZE (1..maxNrofSlotFormatCombinationsPerSet)) OF SlotFormatCombination + OPTIONAL, -- Need M + positionInDCI INTEGER(0..maxSFI-DCI-PayloadSize-1) OPTIONAL, -- Need M + ..., + [[ + enableConfiguredUL-r16 ENUMERATED {enabled} OPTIONAL -- Need R + ]] + +} + +SlotFormatCombination ::= SEQUENCE { + slotFormatCombinationId SlotFormatCombinationId, + slotFormats SEQUENCE (SIZE (1..maxNrofSlotFormatsPerCombination)) OF INTEGER (0..255) +} + +SlotFormatCombinationId ::= INTEGER (0..maxNrofSlotFormatCombinationsPerSet-1) + +-- TAG-SLOTFORMATCOMBINATIONSPERCELL-STOP +-- TAG-SLOTFORMATINDICATOR-START + +SlotFormatIndicator ::= SEQUENCE { + sfi-RNTI RNTI-Value, + dci-PayloadSize INTEGER (1..maxSFI-DCI-PayloadSize), + slotFormatCombToAddModList SEQUENCE (SIZE(1..maxNrofAggregatedCellsPerCellGroup)) OF SlotFormatCombinationsPerCell + OPTIONAL, -- Need N + slotFormatCombToReleaseList SEQUENCE (SIZE(1..maxNrofAggregatedCellsPerCellGroup)) OF ServCellIndex OPTIONAL, -- Need N + ..., + [[ + availableRB-SetsToAddModList-r16 SEQUENCE (SIZE(1..maxNrofAggregatedCellsPerCellGroup)) OF AvailableRB-SetsPerCell-r16 OPTIONAL, -- Need N + availableRB-SetsToRelease-r16 SEQUENCE (SIZE(1..maxNrofAggregatedCellsPerCellGroup)) OF ServCellIndex OPTIONAL, -- Need N + searchSpaceSwitchTriggerToAddModList-r16 SEQUENCE (SIZE(1..4)) OF SearchSpaceSwitchTrigger-r16 OPTIONAL, -- Need N + searchSpaceSwitchTriggerToReleaseList-r16 SEQUENCE (SIZE(1..4)) OF ServCellIndex OPTIONAL, -- Need N + co-DurationsPerCellToAddModList-r16 SEQUENCE (SIZE(1..maxNrofAggregatedCellsPerCellGroup)) OF CO-DurationsPerCell-r16 OPTIONAL, -- Need N + co-DurationsPerCellToReleaseList-r16 SEQUENCE (SIZE(1..maxNrofAggregatedCellsPerCellGroup)) OF ServCellIndex OPTIONAL -- Need N + ]] +} + +CO-DurationsPerCell-r16 ::= SEQUENCE { + servingCellId-r16 ServCellIndex, + positionInDCI-r16 INTEGER(0..maxSFI-DCI-PayloadSize-1), + subcarrierSpacing-r16 SubcarrierSpacing, + co-DurationList-r16 SEQUENCE (SIZE(1..64)) OF CO-Duration-r16 +} + +CO-Duration-r16 ::= INTEGER (0..1120) + +AvailableRB-SetsPerCell-r16 ::= SEQUENCE { + servingCellId-r16 ServCellIndex, + positionInDCI-r16 INTEGER(0..maxSFI-DCI-PayloadSize-1) +} + +SearchSpaceSwitchTrigger-r16 ::= SEQUENCE { + servingCellId-r16 ServCellIndex, + positionInDCI-r16 INTEGER(0..maxSFI-DCI-PayloadSize-1) +} + +-- TAG-SLOTFORMATINDICATOR-STOP +-- TAG-S-NSSAI-START + +S-NSSAI ::= CHOICE{ + sst BIT STRING (SIZE (8)), + sst-SD BIT STRING (SIZE (32)) +} + +-- TAG-S-NSSAI-STOP +-- TAG-SPEEDSTATESCALEFACTORS-START + +SpeedStateScaleFactors ::= SEQUENCE { + sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0}, + sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0} +} +-- TAG-SPEEDSTATESCALEFACTORS-STOP +-- TAG-SPS-CONFIG-START + +SPS-Config ::= SEQUENCE { + periodicity ENUMERATED {ms10, ms20, ms32, ms40, ms64, ms80, ms128, ms160, ms320, ms640, + spare6, spare5, spare4, spare3, spare2, spare1}, + nrofHARQ-Processes INTEGER (1..8), + n1PUCCH-AN PUCCH-ResourceId OPTIONAL, -- Need M + mcs-Table ENUMERATED {qam64LowSE} OPTIONAL, -- Need S + ..., + [[ + sps-ConfigIndex-r16 SPS-ConfigIndex-r16 OPTIONAL, -- Cond SPS-List + harq-ProcID-Offset-r16 INTEGER (0..15) OPTIONAL, -- Need R + periodicityExt-r16 INTEGER (1..5120) OPTIONAL, -- Need R + harq-CodebookID-r16 INTEGER (1..2) OPTIONAL, -- Need R + pdsch-AggregationFactor-r16 ENUMERATED {n1, n2, n4, n8 } OPTIONAL -- Need S + ]] +} + +-- TAG-SPS-CONFIG-STOP +-- TAG-SPS-CONFIGINDEX-START + +SPS-ConfigIndex-r16 ::= INTEGER (0.. maxNrofSPS-Config-r16-1) + +-- TAG-SPS-CONFIGINDEX-STOP +-- TAG-SPS-PUCCH-AN-START + +SPS-PUCCH-AN-r16 ::= SEQUENCE { + sps-PUCCH-AN-ResourceID-r16 PUCCH-ResourceId, + maxPayloadSize-r16 INTEGER (4..256) OPTIONAL -- Need R +} + +-- TAG-SPS-PUCCH-AN-STOP +-- TAG-SPS-PUCCH-AN-LIST-START + +SPS-PUCCH-AN-List-r16 ::= SEQUENCE (SIZE(1..4)) OF SPS-PUCCH-AN-r16 + +-- TAG-SPS-PUCCH-AN-LIST-STOP +-- TAG-SRB-IDENTITY-START + +SRB-Identity ::= INTEGER (1..3) + +-- TAG-SRB-IDENTITY-STOP +-- TAG-SRS-CARRIERSWITCHING-START + +SRS-CarrierSwitching ::= SEQUENCE { + srs-SwitchFromServCellIndex INTEGER (0..31) OPTIONAL, -- Need M + srs-SwitchFromCarrier ENUMERATED {sUL, nUL}, + srs-TPC-PDCCH-Group CHOICE { + typeA SEQUENCE (SIZE (1..32)) OF SRS-TPC-PDCCH-Config, + typeB SRS-TPC-PDCCH-Config + } OPTIONAL, -- Need M + monitoringCells SEQUENCE (SIZE (1..maxNrofServingCells)) OF ServCellIndex OPTIONAL, -- Need M + ... +} + +SRS-TPC-PDCCH-Config ::= SEQUENCE { + srs-CC-SetIndexlist SEQUENCE (SIZE(1..4)) OF SRS-CC-SetIndex OPTIONAL -- Need M +} + +SRS-CC-SetIndex ::= SEQUENCE { + cc-SetIndex INTEGER (0..3) OPTIONAL, -- Need M + cc-IndexInOneCC-Set INTEGER (0..7) OPTIONAL -- Need M +} + +-- TAG-SRS-CARRIERSWITCHING-STOP +-- TAG-SRS-CONFIG-START + +SRS-Config ::= SEQUENCE { + srs-ResourceSetToReleaseList SEQUENCE (SIZE(1..maxNrofSRS-ResourceSets)) OF SRS-ResourceSetId OPTIONAL, -- Need N + srs-ResourceSetToAddModList SEQUENCE (SIZE(1..maxNrofSRS-ResourceSets)) OF SRS-ResourceSet OPTIONAL, -- Need N + srs-ResourceToReleaseList SEQUENCE (SIZE(1..maxNrofSRS-Resources)) OF SRS-ResourceId OPTIONAL, -- Need N + srs-ResourceToAddModList SEQUENCE (SIZE(1..maxNrofSRS-Resources)) OF SRS-Resource OPTIONAL, -- Need N + tpc-Accumulation ENUMERATED {disabled} OPTIONAL, -- Need S + ..., + [[ + srs-RequestForDCI-Format1-2-r16 INTEGER (1..2) OPTIONAL, -- Need S + srs-RequestForDCI-Format0-2-r16 INTEGER (1..2) OPTIONAL, -- Need S + srs-ResourceSetToAddModListForDCI-Format0-2-r16 SEQUENCE (SIZE(1..maxNrofSRS-ResourceSets)) OF SRS-ResourceSet OPTIONAL, -- Need N + srs-ResourceSetToReleaseListForDCI-Format0-2-r16 SEQUENCE (SIZE(1..maxNrofSRS-ResourceSets)) OF SRS-ResourceSetId OPTIONAL,-- Need N + srs-PosResourceSetToReleaseList-r16 SEQUENCE (SIZE(1..maxNrofSRS-PosResourceSets-r16)) OF SRS-PosResourceSetId-r16 + OPTIONAL, -- Need N + srs-PosResourceSetToAddModList-r16 SEQUENCE (SIZE(1..maxNrofSRS-PosResourceSets-r16)) OF SRS-PosResourceSet-r16 OPTIONAL,-- Need N + srs-PosResourceToReleaseList-r16 SEQUENCE (SIZE(1..maxNrofSRS-PosResources-r16)) OF SRS-PosResourceId-r16 OPTIONAL,-- Need N + srs-PosResourceToAddModList-r16 SEQUENCE (SIZE(1..maxNrofSRS-PosResources-r16)) OF SRS-PosResource-r16 OPTIONAL -- Need N + ]] +} + +SRS-ResourceSet ::= SEQUENCE { + srs-ResourceSetId SRS-ResourceSetId, + srs-ResourceIdList SEQUENCE (SIZE(1..maxNrofSRS-ResourcesPerSet)) OF SRS-ResourceId OPTIONAL, -- Cond Setup + resourceType CHOICE { + aperiodic SEQUENCE { + aperiodicSRS-ResourceTrigger INTEGER (1..maxNrofSRS-TriggerStates-1), + csi-RS NZP-CSI-RS-ResourceId OPTIONAL, -- Cond NonCodebook + slotOffset INTEGER (1..32) OPTIONAL, -- Need S + ..., + [[ + aperiodicSRS-ResourceTriggerList SEQUENCE (SIZE(1..maxNrofSRS-TriggerStates-2)) + OF INTEGER (1..maxNrofSRS-TriggerStates-1) OPTIONAL -- Need M + ]] + }, + semi-persistent SEQUENCE { + associatedCSI-RS NZP-CSI-RS-ResourceId OPTIONAL, -- Cond NonCodebook + ... + }, + periodic SEQUENCE { + associatedCSI-RS NZP-CSI-RS-ResourceId OPTIONAL, -- Cond NonCodebook + ... + } + }, + usage ENUMERATED {beamManagement, codebook, nonCodebook, antennaSwitching}, + alpha Alpha OPTIONAL, -- Need S + p0 INTEGER (-202..24) OPTIONAL, -- Cond Setup + pathlossReferenceRS PathlossReferenceRS-Config OPTIONAL, -- Need M + srs-PowerControlAdjustmentStates ENUMERATED { sameAsFci2, separateClosedLoop} OPTIONAL, -- Need S + ..., + [[ + pathlossReferenceRSList-r16 SetupRelease { PathlossReferenceRSList-r16} OPTIONAL -- Need M + ]] +} + +PathlossReferenceRS-Config ::= CHOICE { + ssb-Index SSB-Index, + csi-RS-Index NZP-CSI-RS-ResourceId +} + +PathlossReferenceRSList-r16 ::= SEQUENCE (SIZE (1..maxNrofSRS-PathlossReferenceRS-r16)) OF PathlossReferenceRS-r16 + +PathlossReferenceRS-r16 ::= SEQUENCE { + srs-PathlossReferenceRS-Id-r16 SRS-PathlossReferenceRS-Id-r16, + pathlossReferenceRS-r16 PathlossReferenceRS-Config +} + +SRS-PathlossReferenceRS-Id-r16 ::= INTEGER (0..maxNrofSRS-PathlossReferenceRS-1-r16) + +SRS-PosResourceSet-r16 ::= SEQUENCE { + srs-PosResourceSetId-r16 SRS-PosResourceSetId-r16, + srs-PosResourceIdList-r16 SEQUENCE (SIZE(1..maxNrofSRS-ResourcesPerSet)) OF SRS-PosResourceId-r16 + OPTIONAL, -- Cond Setup + resourceType-r16 CHOICE { + aperiodic-r16 SEQUENCE { + aperiodicSRS-ResourceTriggerList-r16 SEQUENCE (SIZE(1..maxNrofSRS-TriggerStates-1)) + OF INTEGER (1..maxNrofSRS-TriggerStates-1) OPTIONAL, -- Need M + ... + }, + semi-persistent-r16 SEQUENCE { + ... + }, + periodic-r16 SEQUENCE { + ... + } + }, + alpha-r16 Alpha OPTIONAL, -- Need S + p0-r16 INTEGER (-202..24) OPTIONAL, -- Cond Setup + pathlossReferenceRS-Pos-r16 CHOICE { + ssb-IndexServing-r16 SSB-Index, + ssb-Ncell-r16 SSB-InfoNcell-r16, + dl-PRS-r16 DL-PRS-Info-r16 + } OPTIONAL, -- Need M + ... +} + +SRS-ResourceSetId ::= INTEGER (0..maxNrofSRS-ResourceSets-1) + +SRS-PosResourceSetId-r16 ::= INTEGER (0..maxNrofSRS-PosResourceSets-1-r16) + +SRS-Resource ::= SEQUENCE { + srs-ResourceId SRS-ResourceId, + nrofSRS-Ports ENUMERATED {port1, ports2, ports4}, + ptrs-PortIndex ENUMERATED {n0, n1 } OPTIONAL, -- Need R + transmissionComb CHOICE { + n2 SEQUENCE { + combOffset-n2 INTEGER (0..1), + cyclicShift-n2 INTEGER (0..7) + }, + n4 SEQUENCE { + combOffset-n4 INTEGER (0..3), + cyclicShift-n4 INTEGER (0..11) + } + }, + resourceMapping SEQUENCE { + startPosition INTEGER (0..5), + nrofSymbols ENUMERATED {n1, n2, n4}, + repetitionFactor ENUMERATED {n1, n2, n4} + }, + freqDomainPosition INTEGER (0..67), + freqDomainShift INTEGER (0..268), + freqHopping SEQUENCE { + c-SRS INTEGER (0..63), + b-SRS INTEGER (0..3), + b-hop INTEGER (0..3) + }, + groupOrSequenceHopping ENUMERATED { neither, groupHopping, sequenceHopping }, + resourceType CHOICE { + aperiodic SEQUENCE { + ... + }, + semi-persistent SEQUENCE { + periodicityAndOffset-sp SRS-PeriodicityAndOffset, + ... + }, + periodic SEQUENCE { + periodicityAndOffset-p SRS-PeriodicityAndOffset, + ... + } + }, + sequenceId INTEGER (0..1023), + spatialRelationInfo SRS-SpatialRelationInfo OPTIONAL, -- Need R + ..., + [[ + resourceMapping-r16 SEQUENCE { + startPosition-r16 INTEGER (0..13), + nrofSymbols-r16 ENUMERATED {n1, n2, n4}, + repetitionFactor-r16 ENUMERATED {n1, n2, n4} + } OPTIONAL -- Need R + ]] + +} + +SRS-PosResource-r16::= SEQUENCE { + srs-PosResourceId-r16 SRS-PosResourceId-r16, + transmissionComb-r16 CHOICE { + n2-r16 SEQUENCE { + combOffset-n2-r16 INTEGER (0..1), + cyclicShift-n2-r16 INTEGER (0..7) + }, + n4-r16 SEQUENCE { + combOffset-n4-16 INTEGER (0..3), + cyclicShift-n4-r16 INTEGER (0..11) + }, + n8-r16 SEQUENCE { + combOffset-n8-r16 INTEGER (0..7), + cyclicShift-n8-r16 INTEGER (0..5) + }, + ... + }, + resourceMapping-r16 SEQUENCE { + startPosition-r16 INTEGER (0..13), + nrofSymbols-r16 ENUMERATED {n1, n2, n4, n8, n12} + }, + freqDomainShift-r16 INTEGER (0..268), + freqHopping-r16 SEQUENCE { + c-SRS-r16 INTEGER (0..63), + ... + }, + groupOrSequenceHopping-r16 ENUMERATED { neither, groupHopping, sequenceHopping }, + resourceType-r16 CHOICE { + aperiodic-r16 SEQUENCE { + slotOffset-r16 INTEGER (1..32) OPTIONAL, -- Need S + ... + }, + semi-persistent-r16 SEQUENCE { + periodicityAndOffset-sp-r16 SRS-PeriodicityAndOffset-r16, + ... + }, + periodic-r16 SEQUENCE { + periodicityAndOffset-p-r16 SRS-PeriodicityAndOffset-r16, + ... + } + }, + sequenceId-r16 INTEGER (0..65535), + spatialRelationInfoPos-r16 SRS-SpatialRelationInfoPos-r16 OPTIONAL, -- Need R + ... +} + +SRS-SpatialRelationInfo ::= SEQUENCE { + servingCellId ServCellIndex OPTIONAL, -- Need S + referenceSignal CHOICE { + ssb-Index SSB-Index, + csi-RS-Index NZP-CSI-RS-ResourceId, + srs SEQUENCE { + resourceId SRS-ResourceId, + uplinkBWP BWP-Id + } + } +} + +SRS-SpatialRelationInfoPos-r16 ::= CHOICE { + servingRS-r16 SEQUENCE { + servingCellId ServCellIndex OPTIONAL, -- Need S + referenceSignal-r16 CHOICE { + ssb-IndexServing-r16 SSB-Index, + csi-RS-IndexServing-r16 NZP-CSI-RS-ResourceId, + srs-SpatialRelation-r16 SEQUENCE { + resourceSelection-r16 CHOICE { + srs-ResourceId-r16 SRS-ResourceId, + srs-PosResourceId-r16 SRS-PosResourceId-r16 + }, + uplinkBWP-r16 BWP-Id + } + } + }, + ssb-Ncell-r16 SSB-InfoNcell-r16, + dl-PRS-r16 DL-PRS-Info-r16 +} + +SSB-Configuration-r16 ::= SEQUENCE { + ssb-Freq-r16 ARFCN-ValueNR, + halfFrameIndex-r16 ENUMERATED {zero, one}, + ssbSubcarrierSpacing-r16 SubcarrierSpacing, + ssb-Periodicity-r16 ENUMERATED { ms5, ms10, ms20, ms40, ms80, ms160, spare2,spare1 } OPTIONAL, -- Need S + sfn0-Offset-r16 SEQUENCE { + sfn-Offset-r16 INTEGER (0..1023), + integerSubframeOffset-r16 INTEGER (0..9) OPTIONAL -- Need R + } OPTIONAL, -- Need R + sfn-SSB-Offset-r16 INTEGER (0..15), + ss-PBCH-BlockPower-r16 INTEGER (-60..50) OPTIONAL -- Cond Pathloss +} + +SSB-InfoNcell-r16 ::= SEQUENCE { + physicalCellId-r16 PhysCellId, + ssb-IndexNcell-r16 SSB-Index OPTIONAL, -- Need S + ssb-Configuration-r16 SSB-Configuration-r16 OPTIONAL -- Need S +} + +DL-PRS-Info-r16 ::= SEQUENCE { + dl-PRS-ID-r16 INTEGER (0..255), + dl-PRS-ResourceSetId-r16 INTEGER (0..7), + dl-PRS-ResourceId-r16 INTEGER (0..63) OPTIONAL -- Need S +} + +SRS-ResourceId ::= INTEGER (0..maxNrofSRS-Resources-1) +SRS-PosResourceId-r16 ::= INTEGER (0..maxNrofSRS-PosResources-1-r16) + +SRS-PeriodicityAndOffset ::= CHOICE { + sl1 NULL, + sl2 INTEGER(0..1), + sl4 INTEGER(0..3), + sl5 INTEGER(0..4), + sl8 INTEGER(0..7), + sl10 INTEGER(0..9), + sl16 INTEGER(0..15), + sl20 INTEGER(0..19), + sl32 INTEGER(0..31), + sl40 INTEGER(0..39), + sl64 INTEGER(0..63), + sl80 INTEGER(0..79), + sl160 INTEGER(0..159), + sl320 INTEGER(0..319), + sl640 INTEGER(0..639), + sl1280 INTEGER(0..1279), + sl2560 INTEGER(0..2559) +} + +SRS-PeriodicityAndOffset-r16 ::= CHOICE { + sl1 NULL, + sl2 INTEGER(0..1), + sl4 INTEGER(0..3), + sl5 INTEGER(0..4), + sl8 INTEGER(0..7), + sl10 INTEGER(0..9), + sl16 INTEGER(0..15), + sl20 INTEGER(0..19), + sl32 INTEGER(0..31), + sl40 INTEGER(0..39), + sl64 INTEGER(0..63), + sl80 INTEGER(0..79), + sl160 INTEGER(0..159), + sl320 INTEGER(0..319), + sl640 INTEGER(0..639), + sl1280 INTEGER(0..1279), + sl2560 INTEGER(0..2559), + sl5120 INTEGER(0..5119), + sl10240 INTEGER(0..10239), + sl40960 INTEGER(0..40959), + sl81920 INTEGER(0..81919), + ... +} + +-- TAG-SRS-CONFIG-STOP +-- TAG-SRS-RSRP-RANGE-START + +SRS-RSRP-Range-r16 ::= INTEGER(0..98) + +-- TAG-SRS-RSRP-RANGE-STOP +-- TAG-SRS-TPC-COMMANDCONFIG-START + +SRS-TPC-CommandConfig ::= SEQUENCE { + startingBitOfFormat2-3 INTEGER (1..31) OPTIONAL, -- Need R + fieldTypeFormat2-3 INTEGER (0..1) OPTIONAL, -- Need R + ..., + [[ + startingBitOfFormat2-3SUL INTEGER (1..31) OPTIONAL -- Need R + ]] +} + +-- TAG-SRS-TPC-COMMANDCONFIG-STOP +-- TAG-SSB-INDEX-START + +SSB-Index ::= INTEGER (0..maxNrofSSBs-1) + +-- TAG-SSB-INDEX-STOP +-- TAG-SSB-MTC-START + +SSB-MTC ::= SEQUENCE { + periodicityAndOffset CHOICE { + sf5 INTEGER (0..4), + sf10 INTEGER (0..9), + sf20 INTEGER (0..19), + sf40 INTEGER (0..39), + sf80 INTEGER (0..79), + sf160 INTEGER (0..159) + }, + duration ENUMERATED { sf1, sf2, sf3, sf4, sf5 } +} + +SSB-MTC2 ::= SEQUENCE { + pci-List SEQUENCE (SIZE (1..maxNrofPCIsPerSMTC)) OF PhysCellId OPTIONAL, -- Need M + periodicity ENUMERATED {sf5, sf10, sf20, sf40, sf80, spare3, spare2, spare1} +} + +SSB-MTC2-LP-r16 ::= SEQUENCE { + pci-List SEQUENCE (SIZE (1..maxNrofPCIsPerSMTC)) OF PhysCellId OPTIONAL, -- Need R + periodicity ENUMERATED {sf10, sf20, sf40, sf80, sf160, spare3, spare2, spare1} +} + +SSB-MTC3-r16 ::= SEQUENCE { + periodicityAndOffset-r16 CHOICE { + sf5-r16 INTEGER (0..4), + sf10-r16 INTEGER (0..9), + sf20-r16 INTEGER (0..19), + sf40-r16 INTEGER (0..39), + sf80-r16 INTEGER (0..79), + sf160-r16 INTEGER (0..159), + sf320-r16 INTEGER (0..319), + sf640-r16 INTEGER (0..639), + sf1280-r16 INTEGER (0..1279) + }, + duration-r16 ENUMERATED {sf1, sf2, sf3, sf4, sf5}, + pci-List-r16 SEQUENCE (SIZE (1..maxNrofPCIsPerSMTC)) OF PhysCellId OPTIONAL, -- Need M + ssb-ToMeasure-r16 SetupRelease { SSB-ToMeasure } OPTIONAL -- Need M +} + + +-- TAG-SSB-MTC-STOP +-- TAG-SSB-POSITIONQCL-RELATION-START + +SSB-PositionQCL-Relation-r16 ::= ENUMERATED {n1,n2,n4,n8} + +-- TAG-SSB-POSITIONQCL-RELATION-STOP +-- TAG-SSB-TOMEASURE-START + +SSB-ToMeasure ::= CHOICE { + shortBitmap BIT STRING (SIZE (4)), + mediumBitmap BIT STRING (SIZE (8)), + longBitmap BIT STRING (SIZE (64)) +} + +-- TAG-SSB-TOMEASURE-STOP +-- TAG-SS-RSSI-MEASUREMENT-START + +SS-RSSI-Measurement ::= SEQUENCE { + measurementSlots BIT STRING (SIZE (1..80)), + endSymbol INTEGER(0..3) +} + +-- TAG-SS-RSSI-MEASUREMENT-STOP +-- TAG-SUBCARRIERSPACING-START + +SubcarrierSpacing ::= ENUMERATED {kHz15, kHz30, kHz60, kHz120, kHz240, spare3, spare2, spare1} + +-- TAG-SUBCARRIERSPACING-STOP +-- TAG-TAG-CONFIG-START + +TAG-Config ::= SEQUENCE { + tag-ToReleaseList SEQUENCE (SIZE (1..maxNrofTAGs)) OF TAG-Id OPTIONAL, -- Need N + tag-ToAddModList SEQUENCE (SIZE (1..maxNrofTAGs)) OF TAG OPTIONAL -- Need N +} + +TAG ::= SEQUENCE { + tag-Id TAG-Id, + timeAlignmentTimer TimeAlignmentTimer, + ... +} + +TAG-Id ::= INTEGER (0..maxNrofTAGs-1) + +TimeAlignmentTimer ::= ENUMERATED {ms500, ms750, ms1280, ms1920, ms2560, ms5120, ms10240, infinity} + +-- TAG-TAG-CONFIG-STOP +-- TAG-TCI-STATE-START + +TCI-State ::= SEQUENCE { + tci-StateId TCI-StateId, + qcl-Type1 QCL-Info, + qcl-Type2 QCL-Info OPTIONAL, -- Need R + ... +} + +QCL-Info ::= SEQUENCE { + cell ServCellIndex OPTIONAL, -- Need R + bwp-Id BWP-Id OPTIONAL, -- Cond CSI-RS-Indicated + referenceSignal CHOICE { + csi-rs NZP-CSI-RS-ResourceId, + ssb SSB-Index + }, + qcl-Type ENUMERATED {typeA, typeB, typeC, typeD}, + ... +} + +-- TAG-TCI-STATE-STOP +-- TAG-TCI-STATEID-START + +TCI-StateId ::= INTEGER (0..maxNrofTCI-States-1) + +-- TAG-TCI-STATEID-STOP +-- TAG-TDD-UL-DL-CONFIGCOMMON-START + +TDD-UL-DL-ConfigCommon ::= SEQUENCE { + referenceSubcarrierSpacing SubcarrierSpacing, + pattern1 TDD-UL-DL-Pattern, + pattern2 TDD-UL-DL-Pattern OPTIONAL, -- Need R + ... +} + +TDD-UL-DL-Pattern ::= SEQUENCE { + dl-UL-TransmissionPeriodicity ENUMERATED {ms0p5, ms0p625, ms1, ms1p25, ms2, ms2p5, ms5, ms10}, + nrofDownlinkSlots INTEGER (0..maxNrofSlots), + nrofDownlinkSymbols INTEGER (0..maxNrofSymbols-1), + nrofUplinkSlots INTEGER (0..maxNrofSlots), + nrofUplinkSymbols INTEGER (0..maxNrofSymbols-1), + ..., + [[ + dl-UL-TransmissionPeriodicity-v1530 ENUMERATED {ms3, ms4} OPTIONAL -- Need R + ]] +} + +-- TAG-TDD-UL-DL-CONFIGCOMMON-STOP +-- TAG-TDD-UL-DL-CONFIGDEDICATED-START + +TDD-UL-DL-ConfigDedicated ::= SEQUENCE { + slotSpecificConfigurationsToAddModList SEQUENCE (SIZE (1..maxNrofSlots)) OF TDD-UL-DL-SlotConfig OPTIONAL, -- Need N + slotSpecificConfigurationsToReleaseList SEQUENCE (SIZE (1..maxNrofSlots)) OF TDD-UL-DL-SlotIndex OPTIONAL, -- Need N + ... +} + +TDD-UL-DL-ConfigDedicated-IAB-MT-r16::= SEQUENCE { + slotSpecificConfigurationsToAddModList-IAB-MT-r16 SEQUENCE (SIZE (1..maxNrofSlots)) OF TDD-UL-DL-SlotConfig-IAB-MT-r16 OPTIONAL, -- Need N + slotSpecificConfigurationsToReleaseList-IAB-MT-r16 SEQUENCE (SIZE (1..maxNrofSlots)) OF TDD-UL-DL-SlotIndex OPTIONAL, -- Need N + ... +} + +TDD-UL-DL-SlotConfig ::= SEQUENCE { + slotIndex TDD-UL-DL-SlotIndex, + symbols CHOICE { + allDownlink NULL, + allUplink NULL, + explicit SEQUENCE { + nrofDownlinkSymbols INTEGER (1..maxNrofSymbols-1) OPTIONAL, -- Need S + nrofUplinkSymbols INTEGER (1..maxNrofSymbols-1) OPTIONAL -- Need S + } + } +} + +TDD-UL-DL-SlotConfig-IAB-MT-r16::= SEQUENCE { + slotIndex-r16 TDD-UL-DL-SlotIndex, + symbols-IAB-MT-r16 CHOICE { + allDownlink-r16 NULL, + allUplink-r16 NULL, + explicit-r16 SEQUENCE { + nrofDownlinkSymbols-r16 INTEGER (1..maxNrofSymbols-1) OPTIONAL, -- Need FFS + nrofUplinkSymbols-r16 INTEGER (1..maxNrofSymbols-1) OPTIONAL -- Need FFS + }, + explicit-IAB-MT-r16 SEQUENCE { + nrofDownlinkSymbols-r16 INTEGER (1..maxNrofSymbols-1) OPTIONAL, -- Need FFS + nrofUplinkSymbols-r16 INTEGER (1..maxNrofSymbols-1) OPTIONAL -- Need FFS + } + } +} + +TDD-UL-DL-SlotIndex ::= INTEGER (0..maxNrofSlots-1) + +-- TAG-TDD-UL-DL-CONFIGDEDICATED-STOP +-- TAG-TRACKINGAREACODE-START + +TrackingAreaCode ::= BIT STRING (SIZE (24)) + +-- TAG-TRACKINGAREACODE-STOP +-- TAG-TRESELECTION-START + +T-Reselection ::= INTEGER (0..7) + +-- TAG-TRESELECTION-STOP +-- TAG-TIMETOTRIGGER-START + +TimeToTrigger ::= ENUMERATED { + ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256, + ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560, + ms5120} + +-- TAG-TIMETOTRIGGER-STOP +-- TAG-UAC-BARRINGINFOSETINDEX-START + +UAC-BarringInfoSetIndex ::= INTEGER (1..maxBarringInfoSet) + +-- TAG-UAC-BARRINGINFOSETINDEX-STOP +-- TAG-UAC-BARRINGINFOSETLIST-START + +UAC-BarringInfoSetList ::= SEQUENCE (SIZE(1..maxBarringInfoSet)) OF UAC-BarringInfoSet + +UAC-BarringInfoSet ::= SEQUENCE { + uac-BarringFactor ENUMERATED {p00, p05, p10, p15, p20, p25, p30, p40, + p50, p60, p70, p75, p80, p85, p90, p95}, + uac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512}, + uac-BarringForAccessIdentity BIT STRING (SIZE(7)) +} + +-- TAG-UAC-BARRINGINFOSETLIST-STOP +-- TAG-UAC-BARRINGPERCATLIST-START + +UAC-BarringPerCatList ::= SEQUENCE (SIZE (1..maxAccessCat-1)) OF UAC-BarringPerCat + +UAC-BarringPerCat ::= SEQUENCE { + accessCategory INTEGER (1..maxAccessCat-1), + uac-barringInfoSetIndex UAC-BarringInfoSetIndex +} + +-- TAG-UAC-BARRINGPERCATLIST-STOP +-- TAG-UAC-BARRINGPERPLMN-LIST-START + +UAC-BarringPerPLMN-List ::= SEQUENCE (SIZE (1.. maxPLMN)) OF UAC-BarringPerPLMN + +UAC-BarringPerPLMN ::= SEQUENCE { + plmn-IdentityIndex INTEGER (1..maxPLMN), + uac-ACBarringListType CHOICE{ + uac-ImplicitACBarringList SEQUENCE (SIZE(maxAccessCat-1)) OF UAC-BarringInfoSetIndex, + uac-ExplicitACBarringList UAC-BarringPerCatList + } OPTIONAL -- Need S +} + +-- TAG-UAC-BARRINGPERPLMN-LIST-STOP +-- TAG-UE-TIMERSANDCONSTANTS-START + +UE-TimersAndConstants ::= SEQUENCE { + t300 ENUMERATED {ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, ms2000}, + t301 ENUMERATED {ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, ms2000}, + t310 ENUMERATED {ms0, ms50, ms100, ms200, ms500, ms1000, ms2000}, + n310 ENUMERATED {n1, n2, n3, n4, n6, n8, n10, n20}, + t311 ENUMERATED {ms1000, ms3000, ms5000, ms10000, ms15000, ms20000, ms30000}, + n311 ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10}, + t319 ENUMERATED {ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, ms2000}, + ... +} + +-- TAG-UE-TIMERSANDCONSTANTS-STOP +-- TAG-ULDELAYVALUECONFIG-START + +UL-DelayValueConfig-r16 ::= SEQUENCE { + delay-DRBlist SEQUENCE (SIZE(1..maxDRB)) OF DRB-Identity +} + +-- TAG-ULDELAYVALUECONFIG-STOP +-- TAG-UPLINKCANCELLATION-START + +UplinkCancellation-r16 ::= SEQUENCE { + ci-RNTI-r16 RNTI-Value, + dci-PayloadSizeForCI-r16 INTEGER (0..maxCI-DCI-PayloadSize-r16), + ci-ConfigurationPerServingCell-r16 SEQUENCE (SIZE (1..maxNrofServingCells)) OF CI-ConfigurationPerServingCell-r16, + ... +} + +CI-ConfigurationPerServingCell-r16 ::= SEQUENCE { + servingCellId ServCellIndex, + positionInDCI-r16 INTEGER (0..maxCI-DCI-PayloadSize-r16-1), + positionInDCI-ForSUL-r16 INTEGER (0..maxCI-DCI-PayloadSize-r16-1) OPTIONAL, -- Cond SUL-Only + ci-PayloadSize-r16 ENUMERATED {n1, n2, n4, n5, n7, n8, n10, n14, n16, n20, n28, n32, n35, n42, n56, n112}, + timeFrequencyRegion-r16 SEQUENCE { + timeDurationForCI-r16 ENUMERATED {n2, n4, n7, n14} OPTIONAL, -- Cond SymbolPeriodicity + timeGranularityForCI-r16 ENUMERATED {n1, n2, n4, n7, n14, n28}, + frequencyRegionForCI-r16 INTEGER (0..37949), + deltaOffset-r16 INTEGER (0..2), + ... + }, + uplinkCancellationPriority-v1610 ENUMERATED {enabled} OPTIONAL -- Need S +} + +-- TAG-UPLINKCANCELLATION-STOP +-- TAG-UPLINKCONFIGCOMMON-START + +UplinkConfigCommon ::= SEQUENCE { + frequencyInfoUL FrequencyInfoUL OPTIONAL, -- Cond InterFreqHOAndServCellAdd + initialUplinkBWP BWP-UplinkCommon OPTIONAL, -- Cond ServCellAdd + dummy TimeAlignmentTimer +} + +-- TAG-UPLINKCONFIGCOMMON-STOP +-- TAG-UPLINKCONFIGCOMMONSIB-START + +UplinkConfigCommonSIB ::= SEQUENCE { + frequencyInfoUL FrequencyInfoUL-SIB, + initialUplinkBWP BWP-UplinkCommon, + timeAlignmentTimerCommon TimeAlignmentTimer +} + +-- TAG-UPLINKCONFIGCOMMONSIB-STOP +-- TAG-UPLINKTXDIRECTCURRENTLIST-START + +UplinkTxDirectCurrentList ::= SEQUENCE (SIZE (1..maxNrofServingCells)) OF UplinkTxDirectCurrentCell + +UplinkTxDirectCurrentCell ::= SEQUENCE { + servCellIndex ServCellIndex, + uplinkDirectCurrentBWP SEQUENCE (SIZE (1..maxNrofBWPs)) OF UplinkTxDirectCurrentBWP, + ..., + [[ + uplinkDirectCurrentBWP-SUL SEQUENCE (SIZE (1..maxNrofBWPs)) OF UplinkTxDirectCurrentBWP OPTIONAL + ]] +} + +UplinkTxDirectCurrentBWP ::= SEQUENCE { + bwp-Id BWP-Id, + shift7dot5kHz BOOLEAN, + txDirectCurrentLocation INTEGER (0..3301) +} + +-- TAG-UPLINKTXDIRECTCURRENTLIST-STOP +-- TAG-ZP-CSI-RS-RESOURCE-START + +ZP-CSI-RS-Resource ::= SEQUENCE { + zp-CSI-RS-ResourceId ZP-CSI-RS-ResourceId, + resourceMapping CSI-RS-ResourceMapping, + periodicityAndOffset CSI-ResourcePeriodicityAndOffset OPTIONAL, --Cond PeriodicOrSemiPersistent + ... +} + +ZP-CSI-RS-ResourceId ::= INTEGER (0..maxNrofZP-CSI-RS-Resources-1) + +-- TAG-ZP-CSI-RS-RESOURCE-STOP +-- TAG-ZP-CSI-RS-RESOURCESET-START + +ZP-CSI-RS-ResourceSet ::= SEQUENCE { + zp-CSI-RS-ResourceSetId ZP-CSI-RS-ResourceSetId, + zp-CSI-RS-ResourceIdList SEQUENCE (SIZE(1..maxNrofZP-CSI-RS-ResourcesPerSet)) OF ZP-CSI-RS-ResourceId, + ... +} + +-- TAG-ZP-CSI-RS-RESOURCESET-STOP +-- TAG-ZP-CSI-RS-RESOURCESETID-START + +ZP-CSI-RS-ResourceSetId ::= INTEGER (0..maxNrofZP-CSI-RS-ResourceSets-1) + +-- TAG-ZP-CSI-RS-RESOURCESETID-STOP +-- TAG-ACCESSSTRATUMRELEASE-START + +AccessStratumRelease ::= ENUMERATED { + rel15, rel16, spare6, spare5, spare4, spare3, spare2, spare1, ... } + +-- TAG-ACCESSSTRATUMRELEASE-STOP +-- TAG-BANDCOMBINATIONLIST-START + +BandCombinationList ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination + +BandCombinationList-v1540 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1540 + +BandCombinationList-v1550 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1550 + +BandCombinationList-v1560 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1560 + +BandCombinationList-v1570 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1570 + +BandCombinationList-v1580 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1580 + +BandCombinationList-v1590 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1590 + +BandCombinationList-v1610 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-v1610 + +BandCombinationList-UplinkTxSwitch-r16 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombination-UplinkTxSwitch-r16 + +BandCombination ::= SEQUENCE { + bandList SEQUENCE (SIZE (1..maxSimultaneousBands)) OF BandParameters, + featureSetCombination FeatureSetCombinationId, + ca-ParametersEUTRA CA-ParametersEUTRA OPTIONAL, + ca-ParametersNR CA-ParametersNR OPTIONAL, + mrdc-Parameters MRDC-Parameters OPTIONAL, + supportedBandwidthCombinationSet BIT STRING (SIZE (1..32)) OPTIONAL, + powerClass-v1530 ENUMERATED {pc2} OPTIONAL +} + +BandCombination-v1540::= SEQUENCE { + bandList-v1540 SEQUENCE (SIZE (1..maxSimultaneousBands)) OF BandParameters-v1540, + ca-ParametersNR-v1540 CA-ParametersNR-v1540 OPTIONAL +} + +BandCombination-v1550 ::= SEQUENCE { + ca-ParametersNR-v1550 CA-ParametersNR-v1550 +} + +BandCombination-v1610 ::= SEQUENCE { + bandList-v1610 SEQUENCE (SIZE (1..maxSimultaneousBands)) OF BandParameters-v1610 OPTIONAL, + ca-ParametersNR-v1610 CA-ParametersNR-v1610 OPTIONAL, + ca-ParametersNRDC-v1610 CA-ParametersNRDC-v1610 OPTIONAL, + powerClass-v1610 ENUMERATED {pc1dot5} OPTIONAL +} + +BandCombination-v1560::= SEQUENCE { + ne-DC-BC ENUMERATED {supported} OPTIONAL, + ca-ParametersNRDC CA-ParametersNRDC OPTIONAL, + ca-ParametersEUTRA-v1560 CA-ParametersEUTRA-v1560 OPTIONAL, + ca-ParametersNR-v1560 CA-ParametersNR-v1560 OPTIONAL +} + +BandCombination-v1570 ::= SEQUENCE { + ca-ParametersEUTRA-v1570 CA-ParametersEUTRA-v1570 +} + +BandCombination-v1580 ::= SEQUENCE { + mrdc-Parameters-v1580 MRDC-Parameters-v1580 +} + +BandCombination-v1590::= SEQUENCE { + supportedBandwidthCombinationSetIntraENDC BIT STRING (SIZE (1..32)) OPTIONAL, + mrdc-Parameters-v1590 MRDC-Parameters-v1590 +} + +BandCombination-UplinkTxSwitch-r16 ::= SEQUENCE { + bandCombination-r16 BandCombination, + bandCombination-v1540 BandCombination-v1540 OPTIONAL, + bandCombination-v1560 BandCombination-v1560 OPTIONAL, + bandCombination-v1570 BandCombination-v1570 OPTIONAL, + bandCombination-v1580 BandCombination-v1580 OPTIONAL, + bandCombination-v1590 BandCombination-v1590 OPTIONAL, + bandCombination-v1610 BandCombination-v1610 OPTIONAL, + supportedBandPairListNR-r16 SEQUENCE (SIZE (1..maxULTxSwitchingBandPairs)) OF ULTxSwitchingBandPair-r16, + uplinkTxSwitching-OptionSupport-r16 ENUMERATED {switchedUL, dualUL, both} OPTIONAL, + ... +} + +ULTxSwitchingBandPair-r16 ::= SEQUENCE { + bandIndexUL1-r16 INTEGER(1..maxSimultaneousBands), + bandIndexUL2-r16 INTEGER(1..maxSimultaneousBands), + uplinkTxSwitchingPeriod-r16 ENUMERATED {n35us, n140us, n210us}, + uplinkTxSwitching-DL-Interruption-r16 BIT STRING (SIZE(1..maxSimultaneousBands)) OPTIONAL +} + +BandParameters ::= CHOICE { + eutra SEQUENCE { + bandEUTRA FreqBandIndicatorEUTRA, + ca-BandwidthClassDL-EUTRA CA-BandwidthClassEUTRA OPTIONAL, + ca-BandwidthClassUL-EUTRA CA-BandwidthClassEUTRA OPTIONAL + }, + nr SEQUENCE { + bandNR FreqBandIndicatorNR, + ca-BandwidthClassDL-NR CA-BandwidthClassNR OPTIONAL, + ca-BandwidthClassUL-NR CA-BandwidthClassNR OPTIONAL + } +} + +BandParameters-v1540 ::= SEQUENCE { + srs-CarrierSwitch CHOICE { + nr SEQUENCE { + srs-SwitchingTimesListNR SEQUENCE (SIZE (1..maxSimultaneousBands)) OF SRS-SwitchingTimeNR + }, + eutra SEQUENCE { + srs-SwitchingTimesListEUTRA SEQUENCE (SIZE (1..maxSimultaneousBands)) OF SRS-SwitchingTimeEUTRA + } + } OPTIONAL, + srs-TxSwitch SEQUENCE { + supportedSRS-TxPortSwitch ENUMERATED {t1r2, t1r4, t2r4, t1r4-t2r4, t1r1, t2r2, t4r4, notSupported}, + txSwitchImpactToRx INTEGER (1..32) OPTIONAL, + txSwitchWithAnotherBand INTEGER (1..32) OPTIONAL + } OPTIONAL +} + +BandParameters-v1610 ::= SEQUENCE { + srs-TxSwitch-v1610 SEQUENCE { + supportedSRS-TxPortSwitch-v1610 ENUMERATED {t1r1-t1r2, t1r1-t1r2-t1r4, t1r1-t1r2-t2r2-t2r4, t1r1-t1r2-t2r2-t1r4-t2r4, + t1r1-t2r2, t1r1-t2r2-t4r4} + } OPTIONAL, + intraFreqDAPS-Parameters-r16 SEQUENCE { + intraFreqDiffSCS-DAPS-r16 ENUMERATED {supported} OPTIONAL, + intraFreqDAPS-r16 ENUMERATED {supported} OPTIONAL, + intraFreqAsyncDAPS-r16 ENUMERATED {supported} OPTIONAL, + intraFreqMultiUL-TransmissionDAPS-r16 ENUMERATED {supported} OPTIONAL, + intraFreqTwoTAGs-DAPS-r16 ENUMERATED {supported} OPTIONAL, + intraFreqSemiStaticPowerSharingDAPS-Mode1-r16 ENUMERATED {supported} OPTIONAL, + intraFreqSemiStaticPowerSharingDAPS-Mode2-r16 ENUMERATED {supported} OPTIONAL, + intraFreqDynamicPowersharingDAPS-r16 ENUMERATED {short, long} OPTIONAL + } OPTIONAL +} + +-- TAG-BANDCOMBINATIONLIST-STOP +-- TAG-BANDCOMBINATIONLISTSIDELINK-START + +BandCombinationListSidelink-r16 ::= SEQUENCE { + supportedBandCombinationListSidelink-r16 SupportedBandCombinationListSidelink-r16 OPTIONAL, + supportedBandCombinationListSidelinkEUTRA-r16 SupportedBandCombinationListSidelinkEUTRA-r16 OPTIONAL, + supportedBandCombinationListSidelinkEUTRA-NR-r16 SupportedBandCombinationListSidelinkEUTRA-NR-r16 OPTIONAL, + ... +} + +SupportedBandCombinationListSidelink-r16 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombinationParametersSidelink-r16 + +BandCombinationParametersSidelink-r16 ::= SEQUENCE (SIZE (1..maxSimultaneousBands)) OF BandParametersSidelink-r16 + +BandParametersSidelink-r16 ::= SEQUENCE { + freqBandSidelink-r16 FreqBandIndicatorNR +} + +SupportedBandCombinationListSidelinkEUTRA-r16 ::= SEQUENCE { + bandCombinationListEUTRA1-r16 OCTET STRING OPTIONAL, + bandCombinationListEUTRA2-r16 OCTET STRING OPTIONAL +} + +SupportedBandCombinationListSidelinkEUTRA-NR-r16 ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombinationParametersSidelinkEUTRA-NR-r16 + +BandCombinationParametersSidelinkEUTRA-NR-r16 ::= SEQUENCE (SIZE (1..maxSimultaneousBands)) OF BandParametersSidelinkEUTRA-NR-r16 + +BandParametersSidelinkEUTRA-NR-r16 ::= CHOICE { + eutra SEQUENCE { + bandParametersSidelinkEUTRA1-r16 OCTET STRING OPTIONAL, + bandParametersSidelinkEUTRA2-r16 OCTET STRING OPTIONAL + }, + nr SEQUENCE { + bandParametersSidelinkNR-r16 BandParametersSidelink-r16 } + } + +-- TAG-BANDCOMBINATIONLISTSIDELINK-STOP +-- TAG-CA-BANDWIDTHCLASSEUTRA-START + +CA-BandwidthClassEUTRA ::= ENUMERATED {a, b, c, d, e, f, ...} + +-- TAG-CA-BANDWIDTHCLASSEUTRA-STOP +-- TAG-CA-BANDWIDTHCLASSNR-START + +CA-BandwidthClassNR ::= ENUMERATED {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, ...} + +-- TAG-CA-BANDWIDTHCLASSNR-STOP +-- TAG-CA-PARAMETERSEUTRA-START + +CA-ParametersEUTRA ::= SEQUENCE { + multipleTimingAdvance ENUMERATED {supported} OPTIONAL, + simultaneousRx-Tx ENUMERATED {supported} OPTIONAL, + supportedNAICS-2CRS-AP BIT STRING (SIZE (1..8)) OPTIONAL, + additionalRx-Tx-PerformanceReq ENUMERATED {supported} OPTIONAL, + ue-CA-PowerClass-N ENUMERATED {class2} OPTIONAL, + supportedBandwidthCombinationSetEUTRA-v1530 BIT STRING (SIZE (1..32)) OPTIONAL, + ... +} + +CA-ParametersEUTRA-v1560 ::= SEQUENCE { + fd-MIMO-TotalWeightedLayers INTEGER (2..128) OPTIONAL +} + +CA-ParametersEUTRA-v1570 ::= SEQUENCE { + dl-1024QAM-TotalWeightedLayers INTEGER (0..10) OPTIONAL +} + +-- TAG-CA-PARAMETERSEUTRA-STOP +-- TAG-CA-PARAMETERSNR-START + +CA-ParametersNR ::= SEQUENCE { + dummy ENUMERATED {supported} OPTIONAL, + parallelTxSRS-PUCCH-PUSCH ENUMERATED {supported} OPTIONAL, + parallelTxPRACH-SRS-PUCCH-PUSCH ENUMERATED {supported} OPTIONAL, + simultaneousRxTxInterBandCA ENUMERATED {supported} OPTIONAL, + simultaneousRxTxSUL ENUMERATED {supported} OPTIONAL, + diffNumerologyAcrossPUCCH-Group ENUMERATED {supported} OPTIONAL, + diffNumerologyWithinPUCCH-GroupSmallerSCS ENUMERATED {supported} OPTIONAL, + supportedNumberTAG ENUMERATED {n2, n3, n4} OPTIONAL, + ... +} + +CA-ParametersNR-v1540 ::= SEQUENCE { + simultaneousSRS-AssocCSI-RS-AllCC INTEGER (5..32) OPTIONAL, + csi-RS-IM-ReceptionForFeedbackPerBandComb SEQUENCE { + maxNumberSimultaneousNZP-CSI-RS-ActBWP-AllCC INTEGER (1..64) OPTIONAL, + totalNumberPortsSimultaneousNZP-CSI-RS-ActBWP-AllCC INTEGER (2..256) OPTIONAL + } OPTIONAL, + simultaneousCSI-ReportsAllCC INTEGER (5..32) OPTIONAL, + dualPA-Architecture ENUMERATED {supported} OPTIONAL +} + +CA-ParametersNR-v1550 ::= SEQUENCE { + dummy ENUMERATED {supported} OPTIONAL +} + +CA-ParametersNR-v1560 ::= SEQUENCE { + diffNumerologyWithinPUCCH-GroupLargerSCS ENUMERATED {supported} OPTIONAL +} + +CA-ParametersNR-v1610 ::= SEQUENCE { + -- R1 9-3: Parallel MsgA and SRS/PUCCH/PUSCH transmissions across CCs in inter-band CA + parallelTxMsgA-SRS-PUCCH-PUSCH-r16 ENUMERATED {supported} OPTIONAL, + -- R1 9-4: MsgA operation in a band combination including SUL + msgA-SUL-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-9c: Joint search space group switching across multiple cells + jointSearchSpaceGroupSwitchingAcrossCells-r16 ENUMERATED {supported} OPTIONAL, + -- R1 14-5: Half-duplex UE behaviour in TDD CA for same SCS + half-DuplexTDD-CA-SameSCS-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-4: SCell dormancy within active time + scellDormancyWithinActiveTime-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-4a: SCell dormancy outside active time + scellDormancyOutsideActiveTime-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-6: Cross-carrier A-CSI RS triggering with different SCS + crossCarrierA-CSI-trigDiffSCS-r16 ENUMERATED {higherA-CSI-SCS,lowerA-CSI-SCS,both} OPTIONAL, + -- R1 18-6a: Default QCL assumption for cross-carrier A-CSI-RS triggering + defaultQCL-CrossCarrierA-CSI-Trig-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-7: CA with non-aligned frame boundaries for inter-band CA + interCA-NonAlignedFrame-r16 ENUMERATED {supported} OPTIONAL, + simul-SRS-Trans-InterBandCA-r16 INTEGER (1..2) OPTIONAL, + daps-Parameters-r16 SEQUENCE { + asyncDAPS-r16 ENUMERATED {supported} OPTIONAL, + interFreqDAPS-r16 ENUMERATED {supported} OPTIONAL, + interFreqDiffSCS-DAPS-r16 ENUMERATED {supported} OPTIONAL, + multiUL-TransmissionDAPS-r16 ENUMERATED {supported} OPTIONAL, + semiStaticPowerSharingDAPS-Mode1-r16 ENUMERATED {supported} OPTIONAL, + semiStaticPowerSharingDAPS-Mode2-r16 ENUMERATED {supported} OPTIONAL, + dynamicPowersharingDAPS-r16 ENUMERATED {short, long} OPTIONAL, + ul-TransCancellationDAPS-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + codebookParametersPerBC-r16 CodebookParameters-v1610 OPTIONAL +} + +-- TAG-CA-PARAMETERSNR-STOP +-- TAG-CA-PARAMETERS-NRDC-START + +CA-ParametersNRDC ::= SEQUENCE { + ca-ParametersNR-ForDC CA-ParametersNR OPTIONAL, + ca-ParametersNR-ForDC-v1540 CA-ParametersNR-v1540 OPTIONAL, + ca-ParametersNR-ForDC-v1550 CA-ParametersNR-v1550 OPTIONAL, + ca-ParametersNR-ForDC-v1560 CA-ParametersNR-v1560 OPTIONAL, + featureSetCombinationDC FeatureSetCombinationId OPTIONAL +} + +CA-ParametersNRDC-v1610 ::= SEQUENCE { + -- R1 18-1: Semi-static power sharing mode1 between MCG and SCG cells of same FR for NR dual connectivity + intraFR-NR-DC-PwrSharingMode1-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-1a: Semi-static power sharing mode 2 between MCG and SCG cells of same FR for NR dual connectivity + intraFR-NR-DC-PwrSharingMode2-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-1b: Dynamic power sharing between MCG and SCG cells of same FR for NR dual connectivity + intraFR-NR-DC-DynamicPwrSharing-r16 ENUMERATED {short, long} OPTIONAL +} + +-- TAG-CA-PARAMETERS-NRDC-STOP +-- TAG-CARRIERAGGREGATIONVARIANT-START + +CarrierAggregationVariant ::= SEQUENCE { + fr1fdd-FR1TDD-CA-SpCellOnFR1FDD ENUMERATED {supported} OPTIONAL, + fr1fdd-FR1TDD-CA-SpCellOnFR1TDD ENUMERATED {supported} OPTIONAL, + fr1fdd-FR2TDD-CA-SpCellOnFR1FDD ENUMERATED {supported} OPTIONAL, + fr1fdd-FR2TDD-CA-SpCellOnFR2TDD ENUMERATED {supported} OPTIONAL, + fr1tdd-FR2TDD-CA-SpCellOnFR1TDD ENUMERATED {supported} OPTIONAL, + fr1tdd-FR2TDD-CA-SpCellOnFR2TDD ENUMERATED {supported} OPTIONAL, + fr1fdd-FR1TDD-FR2TDD-CA-SpCellOnFR1FDD ENUMERATED {supported} OPTIONAL, + fr1fdd-FR1TDD-FR2TDD-CA-SpCellOnFR1TDD ENUMERATED {supported} OPTIONAL, + fr1fdd-FR1TDD-FR2TDD-CA-SpCellOnFR2TDD ENUMERATED {supported} OPTIONAL +} + +-- TAG-CARRIERAGGREGATIONVARIANT-STOP +-- TAG-CODEBOOKPARAMETERS-START + +CodebookParameters ::= SEQUENCE { + type1 SEQUENCE { + singlePanel SEQUENCE { + supportedCSI-RS-ResourceList SEQUENCE (SIZE (1.. maxNrofCSI-RS-Resources)) OF SupportedCSI-RS-Resource, + modes ENUMERATED {mode1, mode1andMode2}, + maxNumberCSI-RS-PerResourceSet INTEGER (1..8) + }, + multiPanel SEQUENCE { + supportedCSI-RS-ResourceList SEQUENCE (SIZE (1.. maxNrofCSI-RS-Resources)) OF SupportedCSI-RS-Resource, + modes ENUMERATED {mode1, mode2, both}, + nrofPanels ENUMERATED {n2, n4}, + maxNumberCSI-RS-PerResourceSet INTEGER (1..8) + } OPTIONAL + }, + type2 SEQUENCE { + supportedCSI-RS-ResourceList SEQUENCE (SIZE (1.. maxNrofCSI-RS-Resources)) OF SupportedCSI-RS-Resource, + parameterLx INTEGER (2..4), + amplitudeScalingType ENUMERATED {wideband, widebandAndSubband}, + amplitudeSubsetRestriction ENUMERATED {supported} OPTIONAL + } OPTIONAL, + type2-PortSelection SEQUENCE { + supportedCSI-RS-ResourceList SEQUENCE (SIZE (1.. maxNrofCSI-RS-Resources)) OF SupportedCSI-RS-Resource, + parameterLx INTEGER (2..4), + amplitudeScalingType ENUMERATED {wideband, widebandAndSubband} + } OPTIONAL +} + +CodebookParameters-v1610 ::= SEQUENCE { + supportedCSI-RS-ResourceListAlt-r16 SEQUENCE { + type1-SinglePanel-r16 SEQUENCE (SIZE (1..maxNrofCSI-RS-Resources)) OF INTEGER (0..maxNrofCSI-RS-ResourcesAlt-1-r16) OPTIONAL, + type1-MultiPanel-r16 SEQUENCE (SIZE (1..maxNrofCSI-RS-Resources)) OF INTEGER (0..maxNrofCSI-RS-ResourcesAlt-1-r16) OPTIONAL, + type2-r16 SEQUENCE (SIZE (1..maxNrofCSI-RS-Resources)) OF INTEGER (0..maxNrofCSI-RS-ResourcesAlt-1-r16) OPTIONAL, + type2-PortSelection-r16 SEQUENCE (SIZE (1..maxNrofCSI-RS-Resources)) OF INTEGER (0..maxNrofCSI-RS-ResourcesAlt-1-r16) OPTIONAL + } OPTIONAL +} + +CodebookVariantsList-r16 ::= SEQUENCE (SIZE (1..maxNrofCSI-RS-ResourcesAlt-r16)) OF SupportedCSI-RS-Resource + +SupportedCSI-RS-Resource ::= SEQUENCE { + maxNumberTxPortsPerResource ENUMERATED {p2, p4, p8, p12, p16, p24, p32}, + maxNumberResourcesPerBand INTEGER (1..64), + totalNumberTxPortsPerBand INTEGER (2..256) +} + +-- TAG-CODEBOOKPARAMETERS-STOP +-- TAG-FEATURESETCOMBINATION-START + +FeatureSetCombination ::= SEQUENCE (SIZE (1..maxSimultaneousBands)) OF FeatureSetsPerBand + +FeatureSetsPerBand ::= SEQUENCE (SIZE (1..maxFeatureSetsPerBand)) OF FeatureSet + +FeatureSet ::= CHOICE { + eutra SEQUENCE { + downlinkSetEUTRA FeatureSetEUTRA-DownlinkId, + uplinkSetEUTRA FeatureSetEUTRA-UplinkId + }, + nr SEQUENCE { + downlinkSetNR FeatureSetDownlinkId, + uplinkSetNR FeatureSetUplinkId + } +} + +-- TAG-FEATURESETCOMBINATION-STOP +-- TAG-FEATURESETCOMBINATIONID-START + +FeatureSetCombinationId ::= INTEGER (0.. maxFeatureSetCombinations) + +-- TAG-FEATURESETCOMBINATIONID-STOP +-- TAG-FEATURESETDOWNLINK-START + +FeatureSetDownlink ::= SEQUENCE { + featureSetListPerDownlinkCC SEQUENCE (SIZE (1..maxNrofServingCells)) OF FeatureSetDownlinkPerCC-Id, + + intraBandFreqSeparationDL FreqSeparationClass OPTIONAL, + scalingFactor ENUMERATED {f0p4, f0p75, f0p8} OPTIONAL, + crossCarrierScheduling-OtherSCS ENUMERATED {supported} OPTIONAL, + scellWithoutSSB ENUMERATED {supported} OPTIONAL, + csi-RS-MeasSCellWithoutSSB ENUMERATED {supported} OPTIONAL, + dummy1 ENUMERATED {supported} OPTIONAL, + type1-3-CSS ENUMERATED {supported} OPTIONAL, + pdcch-MonitoringAnyOccasions ENUMERATED {withoutDCI-Gap, withDCI-Gap} OPTIONAL, + dummy2 ENUMERATED {supported} OPTIONAL, + ue-SpecificUL-DL-Assignment ENUMERATED {supported} OPTIONAL, + searchSpaceSharingCA-DL ENUMERATED {supported} OPTIONAL, + timeDurationForQCL SEQUENCE { + scs-60kHz ENUMERATED {s7, s14, s28} OPTIONAL, + scs-120kHz ENUMERATED {s14, s28} OPTIONAL + } OPTIONAL, + pdsch-ProcessingType1-DifferentTB-PerSlot SEQUENCE { + scs-15kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL, + scs-30kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL, + scs-60kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL, + scs-120kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL + } OPTIONAL, + dummy3 DummyA OPTIONAL, + dummy4 SEQUENCE (SIZE (1.. maxNrofCodebooks)) OF DummyB OPTIONAL, + dummy5 SEQUENCE (SIZE (1.. maxNrofCodebooks)) OF DummyC OPTIONAL, + dummy6 SEQUENCE (SIZE (1.. maxNrofCodebooks)) OF DummyD OPTIONAL, + dummy7 SEQUENCE (SIZE (1.. maxNrofCodebooks)) OF DummyE OPTIONAL +} + +FeatureSetDownlink-v1540 ::= SEQUENCE { + oneFL-DMRS-TwoAdditionalDMRS-DL ENUMERATED {supported} OPTIONAL, + additionalDMRS-DL-Alt ENUMERATED {supported} OPTIONAL, + twoFL-DMRS-TwoAdditionalDMRS-DL ENUMERATED {supported} OPTIONAL, + oneFL-DMRS-ThreeAdditionalDMRS-DL ENUMERATED {supported} OPTIONAL, + pdcch-MonitoringAnyOccasionsWithSpanGap SEQUENCE { + scs-15kHz ENUMERATED {set1, set2, set3} OPTIONAL, + scs-30kHz ENUMERATED {set1, set2, set3} OPTIONAL, + scs-60kHz ENUMERATED {set1, set2, set3} OPTIONAL, + scs-120kHz ENUMERATED {set1, set2, set3} OPTIONAL + } OPTIONAL, + pdsch-SeparationWithGap ENUMERATED {supported} OPTIONAL, + pdsch-ProcessingType2 SEQUENCE { + scs-15kHz ProcessingParameters OPTIONAL, + scs-30kHz ProcessingParameters OPTIONAL, + scs-60kHz ProcessingParameters OPTIONAL + } OPTIONAL, + pdsch-ProcessingType2-Limited SEQUENCE { + differentTB-PerSlot-SCS-30kHz ENUMERATED {upto1, upto2, upto4, upto7} + } OPTIONAL, + dl-MCS-TableAlt-DynamicIndication ENUMERATED {supported} OPTIONAL +} + +FeatureSetDownlink-v15a0 ::= SEQUENCE { + supportedSRS-Resources SRS-Resources OPTIONAL +} + +FeatureSetDownlink-v1610 ::= SEQUENCE { + -- R1 22-4e/4f/4g/4h: CBG based reception for DL with unicast PDSCH(s) per slot per CC with UE processing time Capability 1 + cbgPDSCH-ProcessingType1-DifferentTB-PerSlot SEQUENCE { + scs-15kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL, + scs-30kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL, + scs-60kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL, + scs-120kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL + } OPTIONAL, + + -- R1 22-3e/3f/3g/3h: CBG based reception for DL with unicast PDSCH(s) per slot per CC with UE processing time Capability 2 + cbgPDSCH-ProcessingType2-DifferentTB-PerSlot SEQUENCE { + scs-15kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL, + scs-30kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL, + scs-60kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL, + scs-120kHz ENUMERATED {one-pdsch, upto2, upto4, upto7} OPTIONAL + } OPTIONAL +} + +DummyA ::= SEQUENCE { + maxNumberNZP-CSI-RS-PerCC INTEGER (1..32), + maxNumberPortsAcrossNZP-CSI-RS-PerCC ENUMERATED {p2, p4, p8, p12, p16, p24, p32, p40, p48, p56, p64, p72, p80, + p88, p96, p104, p112, p120, p128, p136, p144, p152, p160, p168, + p176, p184, p192, p200, p208, p216, p224, p232, p240, p248, p256}, + maxNumberCS-IM-PerCC ENUMERATED {n1, n2, n4, n8, n16, n32}, + maxNumberSimultaneousCSI-RS-ActBWP-AllCC ENUMERATED {n5, n6, n7, n8, n9, n10, n12, n14, n16, n18, n20, n22, n24, n26, + n28, n30, n32, n34, n36, n38, n40, n42, n44, n46, n48, n50, n52, + n54, n56, n58, n60, n62, n64}, + totalNumberPortsSimultaneousCSI-RS-ActBWP-AllCC ENUMERATED {p8, p12, p16, p24, p32, p40, p48, p56, p64, p72, p80, + p88, p96, p104, p112, p120, p128, p136, p144, p152, p160, p168, + p176, p184, p192, p200, p208, p216, p224, p232, p240, p248, p256} +} + +DummyB ::= SEQUENCE { + maxNumberTxPortsPerResource ENUMERATED {p2, p4, p8, p12, p16, p24, p32}, + maxNumberResources INTEGER (1..64), + totalNumberTxPorts INTEGER (2..256), + supportedCodebookMode ENUMERATED {mode1, mode1AndMode2}, + maxNumberCSI-RS-PerResourceSet INTEGER (1..8) +} + +DummyC ::= SEQUENCE { + maxNumberTxPortsPerResource ENUMERATED {p8, p16, p32}, + maxNumberResources INTEGER (1..64), + totalNumberTxPorts INTEGER (2..256), + supportedCodebookMode ENUMERATED {mode1, mode2, both}, + supportedNumberPanels ENUMERATED {n2, n4}, + maxNumberCSI-RS-PerResourceSet INTEGER (1..8) +} + +DummyD ::= SEQUENCE { + maxNumberTxPortsPerResource ENUMERATED {p4, p8, p12, p16, p24, p32}, + maxNumberResources INTEGER (1..64), + totalNumberTxPorts INTEGER (2..256), + parameterLx INTEGER (2..4), + amplitudeScalingType ENUMERATED {wideband, widebandAndSubband}, + amplitudeSubsetRestriction ENUMERATED {supported} OPTIONAL, + maxNumberCSI-RS-PerResourceSet INTEGER (1..8) +} + +DummyE ::= SEQUENCE { + maxNumberTxPortsPerResource ENUMERATED {p4, p8, p12, p16, p24, p32}, + maxNumberResources INTEGER (1..64), + totalNumberTxPorts INTEGER (2..256), + parameterLx INTEGER (2..4), + amplitudeScalingType ENUMERATED {wideband, widebandAndSubband}, + maxNumberCSI-RS-PerResourceSet INTEGER (1..8) +} + +-- TAG-FEATURESETDOWNLINK-STOP +-- TAG-FEATURESETDOWNLINKID-START + +FeatureSetDownlinkId ::= INTEGER (0..maxDownlinkFeatureSets) + +-- TAG-FEATURESETDOWNLINKID-STOP +-- TAG-FEATURESETDOWNLINKPERCC-START + +FeatureSetDownlinkPerCC ::= SEQUENCE { + supportedSubcarrierSpacingDL SubcarrierSpacing, + supportedBandwidthDL SupportedBandwidth, + channelBW-90mhz ENUMERATED {supported} OPTIONAL, + maxNumberMIMO-LayersPDSCH MIMO-LayersDL OPTIONAL, + supportedModulationOrderDL ModulationOrder OPTIONAL +} + +-- TAG-FEATURESETDOWNLINKPERCC-STOP +-- TAG-FEATURESETDOWNLINKPERCC-ID-START + +FeatureSetDownlinkPerCC-Id ::= INTEGER (1..maxPerCC-FeatureSets) + +-- TAG-FEATURESETDOWNLINKPERCC-ID-STOP +-- TAG-FEATURESETEUTRADOWNLINKID-START + +FeatureSetEUTRA-DownlinkId ::= INTEGER (0..maxEUTRA-DL-FeatureSets) + +-- TAG-FEATURESETEUTRADOWNLINKID-STOP +-- TAG-FEATURESETEUTRAUPLINKID-START + +FeatureSetEUTRA-UplinkId ::= INTEGER (0..maxEUTRA-UL-FeatureSets) + +-- TAG-FEATURESETEUTRAUPLINKID-STOP +-- TAG-FEATURESETS-START + +FeatureSets ::= SEQUENCE { + featureSetsDownlink SEQUENCE (SIZE (1..maxDownlinkFeatureSets)) OF FeatureSetDownlink OPTIONAL, + featureSetsDownlinkPerCC SEQUENCE (SIZE (1..maxPerCC-FeatureSets)) OF FeatureSetDownlinkPerCC OPTIONAL, + featureSetsUplink SEQUENCE (SIZE (1..maxUplinkFeatureSets)) OF FeatureSetUplink OPTIONAL, + featureSetsUplinkPerCC SEQUENCE (SIZE (1..maxPerCC-FeatureSets)) OF FeatureSetUplinkPerCC OPTIONAL, + ..., + [[ + featureSetsDownlink-v1540 SEQUENCE (SIZE (1..maxDownlinkFeatureSets)) OF FeatureSetDownlink-v1540 OPTIONAL, + featureSetsUplink-v1540 SEQUENCE (SIZE (1..maxUplinkFeatureSets)) OF FeatureSetUplink-v1540 OPTIONAL, + featureSetsUplinkPerCC-v1540 SEQUENCE (SIZE (1..maxPerCC-FeatureSets)) OF FeatureSetUplinkPerCC-v1540 OPTIONAL + ]], + [[ + featureSetsDownlink-v15a0 SEQUENCE (SIZE (1..maxDownlinkFeatureSets)) OF FeatureSetDownlink-v15a0 OPTIONAL + ]], + [[ + featureSetsDownlink-v1610 SEQUENCE (SIZE (1..maxDownlinkFeatureSets)) OF FeatureSetDownlink-v1610 OPTIONAL, + featureSetsUplink-v1610 SEQUENCE (SIZE (1..maxUplinkFeatureSets)) OF FeatureSetUplink-v1610 OPTIONAL + ]] +} + +-- TAG-FEATURESETS-STOP +-- TAG-FEATURESETUPLINK-START + +FeatureSetUplink ::= SEQUENCE { + featureSetListPerUplinkCC SEQUENCE (SIZE (1.. maxNrofServingCells)) OF FeatureSetUplinkPerCC-Id, + scalingFactor ENUMERATED {f0p4, f0p75, f0p8} OPTIONAL, + crossCarrierScheduling-OtherSCS ENUMERATED {supported} OPTIONAL, + intraBandFreqSeparationUL FreqSeparationClass OPTIONAL, + searchSpaceSharingCA-UL ENUMERATED {supported} OPTIONAL, + dummy1 DummyI OPTIONAL, + supportedSRS-Resources SRS-Resources OPTIONAL, + twoPUCCH-Group ENUMERATED {supported} OPTIONAL, + dynamicSwitchSUL ENUMERATED {supported} OPTIONAL, + simultaneousTxSUL-NonSUL ENUMERATED {supported} OPTIONAL, + pusch-ProcessingType1-DifferentTB-PerSlot SEQUENCE { + scs-15kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL, + scs-30kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL, + scs-60kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL, + scs-120kHz ENUMERATED {upto2, upto4, upto7} OPTIONAL + } OPTIONAL, + dummy2 DummyF OPTIONAL +} + +FeatureSetUplink-v1540 ::= SEQUENCE { + zeroSlotOffsetAperiodicSRS ENUMERATED {supported} OPTIONAL, + pa-PhaseDiscontinuityImpacts ENUMERATED {supported} OPTIONAL, + pusch-SeparationWithGap ENUMERATED {supported} OPTIONAL, + pusch-ProcessingType2 SEQUENCE { + scs-15kHz ProcessingParameters OPTIONAL, + scs-30kHz ProcessingParameters OPTIONAL, + scs-60kHz ProcessingParameters OPTIONAL + } OPTIONAL, + ul-MCS-TableAlt-DynamicIndication ENUMERATED {supported} OPTIONAL +} + +FeatureSetUplink-v1610 ::= SEQUENCE { + -- R1 11-5: PUsCH repetition Type B + pusch-RepetitionTypeB-r16 SEQUENCE { + maxNumberPUSCH-Tx-r16 ENUMERATED {n2, n3, n4, n7, n8, n12}, + hoppingScheme-r16 ENUMERATED {interSlotHopping, interRepetitionHopping, both} + } OPTIONAL, + -- R1 11-7: UL cancelation scheme for self-carrier + ul-CancellationSelfCarrier-r16 ENUMERATED {supported} OPTIONAL, + -- R1 11-7a: UL cancelation scheme for cross-carrier + ul-CancellationCrossCarrier-r16 ENUMERATED {supported} OPTIONAL, + -- R1 16-5c: The maximum number of SRS resources in one SRS resource set with usage set to 'codebook' for Mode 2 + ul-FullPwrMode2-MaxSRS-ResInSet ENUMERATED {n1, n2, n4} OPTIONAL, + + -- R1 22-4a/4b/4c/4d: CBG based transmission for UL with unicast PUSCH(s) per slot per CC with UE processing time Capability 1 + cbgPUSCH-ProcessingType1-DifferentTB-PerSlot SEQUENCE { + scs-15kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL, + scs-30kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL, + scs-60kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL, + scs-120kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL + } OPTIONAL, + + -- R1 22-3a/3b/3c/3d: CBG based transmission for UL with unicast PUSCH(s) per slot per CC with UE processing time Capability 2 + cbgPUSCH-ProcessingType2-DifferentTB-PerSlot SEQUENCE { + scs-15kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL, + scs-30kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL, + scs-60kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL, + scs-120kHz ENUMERATED {one-pusch, upto2, upto4, upto7} OPTIONAL + } OPTIONAL, + supportedSRS-PosResources-r16 SRS-AllPosResources-r16 OPTIONAL +} + +SRS-AllPosResources-r16 ::= SEQUENCE { + srs-PosResources-r16 SRS-PosResources-r16, + srs-PosResourceAP-r16 SRS-PosResourceAP-r16 OPTIONAL, + srs-PosResourceSP-r16 SRS-PosResourceSP-r16 OPTIONAL +} + +SRS-PosResources-r16 ::= SEQUENCE { + maxNumberSRS-PosResourceSetPerBWP-r16 ENUMERATED {n1, n2, n4, n8, n12, n16}, + maxNumberSRS-PosResourcesPerBWP-r16 ENUMERATED {n1, n2, n4, n8, n16, n32, n64}, + maxNumberSRS-ResourcesPerBWP-PerSlot-r16 ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10, n12, n14}, + maxNumberPeriodicSRS-PosResourcesPerBWP-r16 ENUMERATED {n1, n2, n4, n8, n16, n32, n64}, + maxNumberPeriodicSRS-PosResourcesPerBWP-PerSlot-r16 ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10, n12, n14} +} + +SRS-PosResourceAP-r16 ::= SEQUENCE { + maxNumberAP-SRS-PosResourcesPerBWP-r16 ENUMERATED {n1, n2, n4, n8, n16, n32, n64}, + maxNumberAP-SRS-PosResourcesPerBWP-PerSlot-r16 ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10, n12, n14} +} + +SRS-PosResourceSP-r16 ::= SEQUENCE { + maxNumberSP-SRS-PosResourcesPerBWP-r16 ENUMERATED {n1, n2, n4, n8, n16, n32, n64}, + maxNumberSP-SRS-PosResourcesPerBWP-PerSlot-r16 ENUMERATED {n1, n2, n3, n4, n5, n6, n8, n10, n12, n14} +} + +SRS-Resources ::= SEQUENCE { + maxNumberAperiodicSRS-PerBWP ENUMERATED {n1, n2, n4, n8, n16}, + maxNumberAperiodicSRS-PerBWP-PerSlot INTEGER (1..6), + maxNumberPeriodicSRS-PerBWP ENUMERATED {n1, n2, n4, n8, n16}, + maxNumberPeriodicSRS-PerBWP-PerSlot INTEGER (1..6), + maxNumberSemiPersistentSRS-PerBWP ENUMERATED {n1, n2, n4, n8, n16}, + maxNumberSemiPersistentSRS-PerBWP-PerSlot INTEGER (1..6), + maxNumberSRS-Ports-PerResource ENUMERATED {n1, n2, n4} +} + +DummyF ::= SEQUENCE { + maxNumberPeriodicCSI-ReportPerBWP INTEGER (1..4), + maxNumberAperiodicCSI-ReportPerBWP INTEGER (1..4), + maxNumberSemiPersistentCSI-ReportPerBWP INTEGER (0..4), + simultaneousCSI-ReportsAllCC INTEGER (5..32) +} + +-- TAG-FEATURESETUPLINK-STOP +-- TAG-FEATURESETUPLINKID-START + +FeatureSetUplinkId ::= INTEGER (0..maxUplinkFeatureSets) + +-- TAG-FEATURESETUPLINKID-STOP +-- TAG-FEATURESETUPLINKPERCC-START + +FeatureSetUplinkPerCC ::= SEQUENCE { + supportedSubcarrierSpacingUL SubcarrierSpacing, + supportedBandwidthUL SupportedBandwidth, + channelBW-90mhz ENUMERATED {supported} OPTIONAL, + mimo-CB-PUSCH SEQUENCE { + maxNumberMIMO-LayersCB-PUSCH MIMO-LayersUL OPTIONAL, + maxNumberSRS-ResourcePerSet INTEGER (1..2) + } OPTIONAL, + maxNumberMIMO-LayersNonCB-PUSCH MIMO-LayersUL OPTIONAL, + supportedModulationOrderUL ModulationOrder OPTIONAL +} +FeatureSetUplinkPerCC-v1540 ::= SEQUENCE { + mimo-NonCB-PUSCH SEQUENCE { + maxNumberSRS-ResourcePerSet INTEGER (1..4), + maxNumberSimultaneousSRS-ResourceTx INTEGER (1..4) + } OPTIONAL +} + +-- TAG-FEATURESETUPLINKPERCC-STOP +-- TAG-FEATURESETUPLINKPERCC-ID-START + +FeatureSetUplinkPerCC-Id ::= INTEGER (1..maxPerCC-FeatureSets) + +-- TAG-FEATURESETUPLINKPERCC-ID-STOP +-- TAG-FREQBANDINDICATOREUTRA-START + +FreqBandIndicatorEUTRA ::= INTEGER (1..maxBandsEUTRA) + +-- TAG-FREQBANDINDICATOREUTRA-STOP +-- TAG-FREQBANDLIST-START + +FreqBandList ::= SEQUENCE (SIZE (1..maxBandsMRDC)) OF FreqBandInformation + +FreqBandInformation ::= CHOICE { + bandInformationEUTRA FreqBandInformationEUTRA, + bandInformationNR FreqBandInformationNR +} + +FreqBandInformationEUTRA ::= SEQUENCE { + bandEUTRA FreqBandIndicatorEUTRA, + ca-BandwidthClassDL-EUTRA CA-BandwidthClassEUTRA OPTIONAL, -- Need N + ca-BandwidthClassUL-EUTRA CA-BandwidthClassEUTRA OPTIONAL -- Need N +} + +FreqBandInformationNR ::= SEQUENCE { + bandNR FreqBandIndicatorNR, + maxBandwidthRequestedDL AggregatedBandwidth OPTIONAL, -- Need N + maxBandwidthRequestedUL AggregatedBandwidth OPTIONAL, -- Need N + maxCarriersRequestedDL INTEGER (1..maxNrofServingCells) OPTIONAL, -- Need N + maxCarriersRequestedUL INTEGER (1..maxNrofServingCells) OPTIONAL -- Need N +} + +AggregatedBandwidth ::= ENUMERATED {mhz50, mhz100, mhz150, mhz200, mhz250, mhz300, mhz350, + mhz400, mhz450, mhz500, mhz550, mhz600, mhz650, mhz700, mhz750, mhz800} + +-- TAG-FREQBANDLIST-STOP +-- TAG-FREQSEPARATIONCLASS-START + +FreqSeparationClass ::= ENUMERATED {c1, c2, c3, ...} + +-- TAG-FREQSEPARATIONCLASS-STOP +-- TAG-HIGHSPEEDPARAMETERS-START + +HighSpeedParameters-r16 ::= SEQUENCE { + measurementEnhancement-r16 ENUMERATED {supported} OPTIONAL, + demodulationEnhancement-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-HIGHSPEEDPARAMETERS-STOP +-- TAG-IMS-PARAMETERS-START + +IMS-Parameters ::= SEQUENCE { + ims-ParametersCommon IMS-ParametersCommon OPTIONAL, + ims-ParametersFRX-Diff IMS-ParametersFRX-Diff OPTIONAL, + ... +} + +IMS-ParametersCommon ::= SEQUENCE { + voiceOverEUTRA-5GC ENUMERATED {supported} OPTIONAL, + ..., + [[ + voiceOverSCG-BearerEUTRA-5GC ENUMERATED {supported} OPTIONAL + ]], + [[ + voiceFallbackIndicationEPS-r16 ENUMERATED {supported} OPTIONAL + ]] +} + +IMS-ParametersFRX-Diff ::= SEQUENCE { + voiceOverNR ENUMERATED {supported} OPTIONAL, + ... +} + +-- TAG-IMS-PARAMETERS-STOP +-- TAG-INTERRAT-PARAMETERS-START + +InterRAT-Parameters ::= SEQUENCE { + eutra EUTRA-Parameters OPTIONAL, + ..., + [[ + utra-FDD-r16 UTRA-FDD-Parameters-r16 OPTIONAL + ]] + +} + +EUTRA-Parameters ::= SEQUENCE { + supportedBandListEUTRA SEQUENCE (SIZE (1..maxBandsEUTRA)) OF FreqBandIndicatorEUTRA, + eutra-ParametersCommon EUTRA-ParametersCommon OPTIONAL, + eutra-ParametersXDD-Diff EUTRA-ParametersXDD-Diff OPTIONAL, + ... +} + +EUTRA-ParametersCommon ::= SEQUENCE { + mfbi-EUTRA ENUMERATED {supported} OPTIONAL, + modifiedMPR-BehaviorEUTRA BIT STRING (SIZE (32)) OPTIONAL, + multiNS-Pmax-EUTRA ENUMERATED {supported} OPTIONAL, + rs-SINR-MeasEUTRA ENUMERATED {supported} OPTIONAL, + ..., + [[ + ne-DC ENUMERATED {supported} OPTIONAL + ]], + [[ + nr-HO-ToEN-DC-r16 ENUMERATED {supported} OPTIONAL + ]] +} + +EUTRA-ParametersXDD-Diff ::= SEQUENCE { + rsrqMeasWidebandEUTRA ENUMERATED {supported} OPTIONAL, + ... +} + +UTRA-FDD-Parameters-r16 ::= SEQUENCE { + supportedBandListUTRA-FDD-r16 SEQUENCE (SIZE (1..maxBandsUTRA-FDD-r16)) OF SupportedBandUTRA-FDD-r16, + ... +} + +SupportedBandUTRA-FDD-r16 ::= ENUMERATED { + bandI, bandII, bandIII, bandIV, bandV, bandVI, + bandVII, bandVIII, bandIX, bandX, bandXI, + bandXII, bandXIII, bandXIV, bandXV, bandXVI, + bandXVII, bandXVIII, bandXIX, bandXX, + bandXXI, bandXXII, bandXXIII, bandXXIV, + bandXXV, bandXXVI, bandXXVII, bandXXVIII, + bandXXIX, bandXXX, bandXXXI, bandXXXII} + +-- TAG-INTERRAT-PARAMETERS-STOP +-- TAG-MAC-PARAMETERS-START + +MAC-Parameters ::= SEQUENCE { + mac-ParametersCommon MAC-ParametersCommon OPTIONAL, + mac-ParametersXDD-Diff MAC-ParametersXDD-Diff OPTIONAL +} + +MAC-Parameters-v1610 ::= SEQUENCE { + mac-ParametersFRX-Diff-r16 MAC-ParametersFRX-Diff-r16 OPTIONAL +} + +MAC-ParametersCommon ::= SEQUENCE { + lcp-Restriction ENUMERATED {supported} OPTIONAL, + dummy ENUMERATED {supported} OPTIONAL, + lch-ToSCellRestriction ENUMERATED {supported} OPTIONAL, + ..., + [[ + recommendedBitRate ENUMERATED {supported} OPTIONAL, + recommendedBitRateQuery ENUMERATED {supported} OPTIONAL + ]], + [[ + recommendedBitRateMultiplier-r16 ENUMERATED {supported} OPTIONAL, + secondaryDRX-Group ENUMERATED {supported} OPTIONAL, + preEmptiveBSR-r16 ENUMERATED {supported} OPTIONAL, + autonomousTransmission-r16 ENUMERATED {supported} OPTIONAL, + lch-PriorityBasedPrioritization-r16 ENUMERATED {supported} OPTIONAL, + lch-ToConfiguredGrantMapping-r16 ENUMERATED {supported} OPTIONAL, + lch-ToGrantPriorityRestriction-r16 ENUMERATED {supported} OPTIONAL, + singlePHR-P-r16 ENUMERATED {supported} OPTIONAL, + ul-LBT-FailureDetectionRecovery-r16 ENUMERATED {supported} OPTIONAL + ]] +} + +MAC-ParametersFRX-Diff-r16 ::= SEQUENCE { + directMCG-SCellActivation-r16 ENUMERATED {supported} OPTIONAL, + directMCG-SCellActivationResume-r16 ENUMERATED {supported} OPTIONAL, + directSCG-SCellActivation-r16 ENUMERATED {supported} OPTIONAL, + directSCG-SCellActivationResume-r16 ENUMERATED {supported} OPTIONAL, + -- R1 19-1: DRX Adaptation + drx-Adaptation-r16 SEQUENCE { + licensedBand-r16 MinTimeGap-r16 OPTIONAL, + unlicensedBand-r16 MinTimeGap-r16 OPTIONAL + } OPTIONAL, + ... +} + +MAC-ParametersXDD-Diff ::= SEQUENCE { + skipUplinkTxDynamic ENUMERATED {supported} OPTIONAL, + logicalChannelSR-DelayTimer ENUMERATED {supported} OPTIONAL, + longDRX-Cycle ENUMERATED {supported} OPTIONAL, + shortDRX-Cycle ENUMERATED {supported} OPTIONAL, + multipleSR-Configurations ENUMERATED {supported} OPTIONAL, + multipleConfiguredGrants ENUMERATED {supported} OPTIONAL, + ... +} + +MinTimeGap-r16 ::= SEQUENCE { + scs-15kHz-r16 ENUMERATED {sl1, sl3} OPTIONAL, + scs-30kHz-r16 ENUMERATED {sl1, sl6} OPTIONAL, + scs-60kHz-r16 ENUMERATED {sl1, sl12} OPTIONAL, + scs-120kHz-r16 ENUMERATED {sl2, sl24} OPTIONAL +} + +-- TAG-MAC-PARAMETERS-STOP +-- TAG-MEASANDMOBPARAMETERS-START + +MeasAndMobParameters ::= SEQUENCE { + measAndMobParametersCommon MeasAndMobParametersCommon OPTIONAL, + measAndMobParametersXDD-Diff MeasAndMobParametersXDD-Diff OPTIONAL, + measAndMobParametersFRX-Diff MeasAndMobParametersFRX-Diff OPTIONAL +} + +MeasAndMobParametersCommon ::= SEQUENCE { + supportedGapPattern BIT STRING (SIZE (22)) OPTIONAL, + ssb-RLM ENUMERATED {supported} OPTIONAL, + ssb-AndCSI-RS-RLM ENUMERATED {supported} OPTIONAL, + ..., + [[ + eventB-MeasAndReport ENUMERATED {supported} OPTIONAL, + handoverFDD-TDD ENUMERATED {supported} OPTIONAL, + eutra-CGI-Reporting ENUMERATED {supported} OPTIONAL, + nr-CGI-Reporting ENUMERATED {supported} OPTIONAL + ]], + [[ + independentGapConfig ENUMERATED {supported} OPTIONAL, + periodicEUTRA-MeasAndReport ENUMERATED {supported} OPTIONAL, + handoverFR1-FR2 ENUMERATED {supported} OPTIONAL, + maxNumberCSI-RS-RRM-RS-SINR ENUMERATED {n4, n8, n16, n32, n64, n96} OPTIONAL + ]], + [[ + nr-CGI-Reporting-ENDC ENUMERATED {supported} OPTIONAL + ]], + [[ + eutra-CGI-Reporting-NEDC ENUMERATED {supported} OPTIONAL, + eutra-CGI-Reporting-NRDC ENUMERATED {supported} OPTIONAL, + nr-CGI-Reporting-NEDC ENUMERATED {supported} OPTIONAL, + nr-CGI-Reporting-NRDC ENUMERATED {supported} OPTIONAL + ]], + [[ + reportAddNeighMeasForPeriodic-r16 ENUMERATED {supported} OPTIONAL, + condHandoverParametersCommon-r16 SEQUENCE { + condHandoverFDD-TDD-r16 ENUMERATED {supported} OPTIONAL, + condHandoverFR1-FR2-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + nr-NeedForGap-Reporting-r16 ENUMERATED {supported} OPTIONAL, + supportedGapPattern-NRonly-r16 BIT STRING (SIZE (10)) OPTIONAL, + supportedGapPattern-NRonly-NEDC-r16 ENUMERATED {supported} OPTIONAL, + maxNumberCLI-RSSI-r16 ENUMERATED {n8, n16, n32, n64} OPTIONAL, + maxNumberCLI-SRS-RSRP-r16 ENUMERATED {n4, n8, n16, n32} OPTIONAL, + maxNumberPerSlotCLI-SRS-RSRP-r16 ENUMERATED {n2, n4, n8} OPTIONAL, + mfbi-IAB-r16 ENUMERATED {supported} OPTIONAL, + multipleNS-And-Pmax-IAB-r16 ENUMERATED {supported} OPTIONAL, + nr-CGI-Reporting-NPN-r16 ENUMERATED {supported} OPTIONAL, + idleInactiveEUTRA-MeasReport-r16 ENUMERATED {supported} OPTIONAL, + idleInactive-ValidityArea-r16 ENUMERATED {supported} OPTIONAL + ]] + +} + +MeasAndMobParametersXDD-Diff ::= SEQUENCE { + intraAndInterF-MeasAndReport ENUMERATED {supported} OPTIONAL, + eventA-MeasAndReport ENUMERATED {supported} OPTIONAL, + ..., + [[ + handoverInterF ENUMERATED {supported} OPTIONAL, + handoverLTE-EPC ENUMERATED {supported} OPTIONAL, + handoverLTE-5GC ENUMERATED {supported} OPTIONAL + ]], + [[ + sftd-MeasNR-Neigh ENUMERATED {supported} OPTIONAL, + sftd-MeasNR-Neigh-DRX ENUMERATED {supported} OPTIONAL + ]], + [[ + condHandoverParametersXDD-Diff-r16 SEQUENCE { + condHandover-r16 ENUMERATED {supported} OPTIONAL, + condHandoverFailure-r16 ENUMERATED {supported} OPTIONAL, + condHandoverTwoTriggerEvents-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + pcellT312-r16 ENUMERATED {supported} OPTIONAL, + handoverIntraF-IAB-r16 ENUMERATED {supported} OPTIONAL, + eutra-AutonomousGaps-r16 ENUMERATED {supported} OPTIONAL, + eutra-AutonomousGapsNEDC-r16 ENUMERATED {supported} OPTIONAL, + eutra-AutonomousGapsNRDC-r16 ENUMERATED {supported} OPTIONAL, + nr-AutonomousGaps-r16 ENUMERATED {supported} OPTIONAL, + nr-AutonomousGaps-ENDC-r16 ENUMERATED {supported} OPTIONAL, + nr-AutonomousGapsNEDC-r16 ENUMERATED {supported} OPTIONAL, + nr-AutonomousGapsNRDC-r16 ENUMERATED {supported} OPTIONAL, + handoverUTRA-FDD-r16 ENUMERATED {supported} OPTIONAL + ]] + +} + +MeasAndMobParametersFRX-Diff ::= SEQUENCE { + ss-SINR-Meas ENUMERATED {supported} OPTIONAL, + csi-RSRP-AndRSRQ-MeasWithSSB ENUMERATED {supported} OPTIONAL, + csi-RSRP-AndRSRQ-MeasWithoutSSB ENUMERATED {supported} OPTIONAL, + csi-SINR-Meas ENUMERATED {supported} OPTIONAL, + csi-RS-RLM ENUMERATED {supported} OPTIONAL, + ..., + [[ + handoverInterF ENUMERATED {supported} OPTIONAL, + handoverLTE-EPC ENUMERATED {supported} OPTIONAL, + handoverLTE-5GC ENUMERATED {supported} OPTIONAL + ]], + [[ + maxNumberResource-CSI-RS-RLM ENUMERATED {n2, n4, n6, n8} OPTIONAL + ]], + [[ + simultaneousRxDataSSB-DiffNumerology ENUMERATED {supported} OPTIONAL + ]], + [[ + nr-AutonomousGaps-r16 ENUMERATED {supported} OPTIONAL, + nr-AutonomousGaps-ENDC-r16 ENUMERATED {supported} OPTIONAL, + handoverUTRA-FDD-r16 ENUMERATED {supported} OPTIONAL, + cli-RSSI-Meas-r16 ENUMERATED {supported} OPTIONAL, + cli-SRS-RSRP-Meas-r16 ENUMERATED {supported} OPTIONAL, + condHandoverParametersFRX-Diff-r16 SEQUENCE { + condHandover-r16 ENUMERATED {supported} OPTIONAL, + condHandoverFailure-r16 ENUMERATED {supported} OPTIONAL, + condHandoverTwoTriggerEvents-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + pcellT312-r16 ENUMERATED {supported} OPTIONAL, + interFrequencyMeas-Nogap-r16 ENUMERATED {supported} OPTIONAL, + simultaneousRxDataSSB-DiffNumerology-Inter-r16 ENUMERATED {supported} OPTIONAL, + handoverIntraF-IAB-r16 ENUMERATED {supported} OPTIONAL, + idleInactiveNR-MeasReport-r16 ENUMERATED {supported} OPTIONAL + ]] +} + +-- TAG-MEASANDMOBPARAMETERS-STOP +-- TAG-MEASANDMOBPARAMETERSMRDC-START + +MeasAndMobParametersMRDC ::= SEQUENCE { + measAndMobParametersMRDC-Common MeasAndMobParametersMRDC-Common OPTIONAL, + measAndMobParametersMRDC-XDD-Diff MeasAndMobParametersMRDC-XDD-Diff OPTIONAL, + measAndMobParametersMRDC-FRX-Diff MeasAndMobParametersMRDC-FRX-Diff OPTIONAL +} + +MeasAndMobParametersMRDC-v1560 ::= SEQUENCE { + measAndMobParametersMRDC-XDD-Diff-v1560 MeasAndMobParametersMRDC-XDD-Diff-v1560 OPTIONAL +} + +MeasAndMobParametersMRDC-v1610 ::= SEQUENCE { + measAndMobParametersMRDC-Common-v1610 MeasAndMobParametersMRDC-Common-v1610 OPTIONAL, + measAndMobParametersMRDC-XDD-Diff-v1610 MeasAndMobParametersMRDC-XDD-Diff-v1610 OPTIONAL, + measAndMobParametersMRDC-FRX-Diff-v1610 MeasAndMobParametersMRDC-FRX-Diff-v1610 OPTIONAL, + interNR-MeasEUTRA-IAB-r16 ENUMERATED {supported} OPTIONAL +} + +MeasAndMobParametersMRDC-Common ::= SEQUENCE { + independentGapConfig ENUMERATED {supported} OPTIONAL +} + +MeasAndMobParametersMRDC-Common-v1610 ::= SEQUENCE { + condPSCellChangeParametersCommon-r16 SEQUENCE { + condPSCellChangeFDD-TDD-r16 ENUMERATED {supported} OPTIONAL, + condPSCellChangeFR1-FR2-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL +} + +MeasAndMobParametersMRDC-XDD-Diff ::= SEQUENCE { + sftd-MeasPSCell ENUMERATED {supported} OPTIONAL, + sftd-MeasNR-Cell ENUMERATED {supported} OPTIONAL +} + +MeasAndMobParametersMRDC-XDD-Diff-v1560 ::= SEQUENCE { + sftd-MeasPSCell-NEDC ENUMERATED {supported} OPTIONAL +} + +MeasAndMobParametersMRDC-XDD-Diff-v1610 ::= SEQUENCE { + condPSCellChangeParametersXDD-Diff-r16 SEQUENCE { + condPSCellChange-r16 ENUMERATED {supported} OPTIONAL, + condPSCellChangeTwoTriggerEvents-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + pscellT312-r16 ENUMERATED {supported} OPTIONAL +} + +MeasAndMobParametersMRDC-FRX-Diff ::= SEQUENCE { + simultaneousRxDataSSB-DiffNumerology ENUMERATED {supported} OPTIONAL +} + +MeasAndMobParametersMRDC-FRX-Diff-v1610 ::= SEQUENCE { + condPSCellChangeParametersFRX-Diff-r16 SEQUENCE { + condPSCellChange-r16 ENUMERATED {supported} OPTIONAL, + condPSCellChangeTwoTriggerEvents-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + pscellT312-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-MEASANDMOBPARAMETERSMRDC-STOP +-- TAG-MIMO-LAYERS-START + +MIMO-LayersDL ::= ENUMERATED {twoLayers, fourLayers, eightLayers} + +MIMO-LayersUL ::= ENUMERATED {oneLayer, twoLayers, fourLayers} + +-- TAG-MIMO-LAYERS-STOP +-- TAG-MIMO-PARAMETERSPERBAND-START + +MIMO-ParametersPerBand ::= SEQUENCE { + tci-StatePDSCH SEQUENCE { + maxNumberConfiguredTCIstatesPerCC ENUMERATED {n4, n8, n16, n32, n64, n128} OPTIONAL, + maxNumberActiveTCI-PerBWP ENUMERATED {n1, n2, n4, n8} OPTIONAL + } OPTIONAL, + additionalActiveTCI-StatePDCCH ENUMERATED {supported} OPTIONAL, + pusch-TransCoherence ENUMERATED {nonCoherent, partialCoherent, fullCoherent} OPTIONAL, + beamCorrespondenceWithoutUL-BeamSweeping ENUMERATED {supported} OPTIONAL, + periodicBeamReport ENUMERATED {supported} OPTIONAL, + aperiodicBeamReport ENUMERATED {supported} OPTIONAL, + sp-BeamReportPUCCH ENUMERATED {supported} OPTIONAL, + sp-BeamReportPUSCH ENUMERATED {supported} OPTIONAL, + dummy1 DummyG OPTIONAL, + maxNumberRxBeam INTEGER (2..8) OPTIONAL, + maxNumberRxTxBeamSwitchDL SEQUENCE { + scs-15kHz ENUMERATED {n4, n7, n14} OPTIONAL, + scs-30kHz ENUMERATED {n4, n7, n14} OPTIONAL, + scs-60kHz ENUMERATED {n4, n7, n14} OPTIONAL, + scs-120kHz ENUMERATED {n4, n7, n14} OPTIONAL, + scs-240kHz ENUMERATED {n4, n7, n14} OPTIONAL + } OPTIONAL, + maxNumberNonGroupBeamReporting ENUMERATED {n1, n2, n4} OPTIONAL, + groupBeamReporting ENUMERATED {supported} OPTIONAL, + uplinkBeamManagement SEQUENCE { + maxNumberSRS-ResourcePerSet-BM ENUMERATED {n2, n4, n8, n16}, + maxNumberSRS-ResourceSet INTEGER (1..8) + } OPTIONAL, + maxNumberCSI-RS-BFD INTEGER (1..64) OPTIONAL, + maxNumberSSB-BFD INTEGER (1..64) OPTIONAL, + maxNumberCSI-RS-SSB-CBD INTEGER (1..256) OPTIONAL, + dummy2 ENUMERATED {supported} OPTIONAL, + twoPortsPTRS-UL ENUMERATED {supported} OPTIONAL, + dummy5 SRS-Resources OPTIONAL, + dummy3 INTEGER (1..4) OPTIONAL, + beamReportTiming SEQUENCE { + scs-15kHz ENUMERATED {sym2, sym4, sym8} OPTIONAL, + scs-30kHz ENUMERATED {sym4, sym8, sym14, sym28} OPTIONAL, + scs-60kHz ENUMERATED {sym8, sym14, sym28} OPTIONAL, + scs-120kHz ENUMERATED {sym14, sym28, sym56} OPTIONAL + } OPTIONAL, + ptrs-DensityRecommendationSetDL SEQUENCE { + scs-15kHz PTRS-DensityRecommendationDL OPTIONAL, + scs-30kHz PTRS-DensityRecommendationDL OPTIONAL, + scs-60kHz PTRS-DensityRecommendationDL OPTIONAL, + scs-120kHz PTRS-DensityRecommendationDL OPTIONAL + } OPTIONAL, + ptrs-DensityRecommendationSetUL SEQUENCE { + scs-15kHz PTRS-DensityRecommendationUL OPTIONAL, + scs-30kHz PTRS-DensityRecommendationUL OPTIONAL, + scs-60kHz PTRS-DensityRecommendationUL OPTIONAL, + scs-120kHz PTRS-DensityRecommendationUL OPTIONAL + } OPTIONAL, + dummy4 DummyH OPTIONAL, + aperiodicTRS ENUMERATED {supported} OPTIONAL, + ..., + [[ + dummy6 ENUMERATED {true} OPTIONAL, + beamManagementSSB-CSI-RS BeamManagementSSB-CSI-RS OPTIONAL, + beamSwitchTiming SEQUENCE { + scs-60kHz ENUMERATED {sym14, sym28, sym48, sym224, sym336} OPTIONAL, + scs-120kHz ENUMERATED {sym14, sym28, sym48, sym224, sym336} OPTIONAL + } OPTIONAL, + codebookParameters CodebookParameters OPTIONAL, + csi-RS-IM-ReceptionForFeedback CSI-RS-IM-ReceptionForFeedback OPTIONAL, + csi-RS-ProcFrameworkForSRS CSI-RS-ProcFrameworkForSRS OPTIONAL, + csi-ReportFramework CSI-ReportFramework OPTIONAL, + csi-RS-ForTracking CSI-RS-ForTracking OPTIONAL, + srs-AssocCSI-RS SEQUENCE (SIZE (1.. maxNrofCSI-RS-Resources)) OF SupportedCSI-RS-Resource OPTIONAL, + spatialRelations SpatialRelations OPTIONAL + ]], + [[ + -- R1 16-2b-0: Support of default QCL assumption with two TCI states + defaultQCL-TwoTCI-r16 ENUMERATED {supported} OPTIONAL, + codebookParametersPerBand-r16 CodebookParameters-v1610 OPTIONAL + ]] + +} + +DummyG ::= SEQUENCE { + maxNumberSSB-CSI-RS-ResourceOneTx ENUMERATED {n8, n16, n32, n64}, + maxNumberSSB-CSI-RS-ResourceTwoTx ENUMERATED {n0, n4, n8, n16, n32, n64}, + supportedCSI-RS-Density ENUMERATED {one, three, oneAndThree} +} + +BeamManagementSSB-CSI-RS ::= SEQUENCE { + maxNumberSSB-CSI-RS-ResourceOneTx ENUMERATED {n0, n8, n16, n32, n64}, + maxNumberCSI-RS-Resource ENUMERATED {n0, n4, n8, n16, n32, n64}, + maxNumberCSI-RS-ResourceTwoTx ENUMERATED {n0, n4, n8, n16, n32, n64}, + supportedCSI-RS-Density ENUMERATED {one, three, oneAndThree} OPTIONAL, + maxNumberAperiodicCSI-RS-Resource ENUMERATED {n0, n1, n4, n8, n16, n32, n64} +} + +DummyH ::= SEQUENCE { + burstLength INTEGER (1..2), + maxSimultaneousResourceSetsPerCC INTEGER (1..8), + maxConfiguredResourceSetsPerCC INTEGER (1..64), + maxConfiguredResourceSetsAllCC INTEGER (1..128) +} + +CSI-RS-ForTracking ::= SEQUENCE { + maxBurstLength INTEGER (1..2), + maxSimultaneousResourceSetsPerCC INTEGER (1..8), + maxConfiguredResourceSetsPerCC INTEGER (1..64), + maxConfiguredResourceSetsAllCC INTEGER (1..256) +} + +CSI-RS-IM-ReceptionForFeedback ::= SEQUENCE { + maxConfigNumberNZP-CSI-RS-PerCC INTEGER (1..64), + maxConfigNumberPortsAcrossNZP-CSI-RS-PerCC INTEGER (2..256), + maxConfigNumberCSI-IM-PerCC ENUMERATED {n1, n2, n4, n8, n16, n32}, + maxNumberSimultaneousNZP-CSI-RS-PerCC INTEGER (1..64), + totalNumberPortsSimultaneousNZP-CSI-RS-PerCC INTEGER (2..256) +} + +CSI-RS-ProcFrameworkForSRS ::= SEQUENCE { + maxNumberPeriodicSRS-AssocCSI-RS-PerBWP INTEGER (1..4), + maxNumberAperiodicSRS-AssocCSI-RS-PerBWP INTEGER (1..4), + maxNumberSP-SRS-AssocCSI-RS-PerBWP INTEGER (0..4), + simultaneousSRS-AssocCSI-RS-PerCC INTEGER (1..8) +} + +CSI-ReportFramework ::= SEQUENCE { + maxNumberPeriodicCSI-PerBWP-ForCSI-Report INTEGER (1..4), + maxNumberAperiodicCSI-PerBWP-ForCSI-Report INTEGER (1..4), + maxNumberSemiPersistentCSI-PerBWP-ForCSI-Report INTEGER (0..4), + maxNumberPeriodicCSI-PerBWP-ForBeamReport INTEGER (1..4), + maxNumberAperiodicCSI-PerBWP-ForBeamReport INTEGER (1..4), + maxNumberAperiodicCSI-triggeringStatePerCC ENUMERATED {n3, n7, n15, n31, n63, n128}, + maxNumberSemiPersistentCSI-PerBWP-ForBeamReport INTEGER (0..4), + simultaneousCSI-ReportsPerCC INTEGER (1..8) +} + +PTRS-DensityRecommendationDL ::= SEQUENCE { + frequencyDensity1 INTEGER (1..276), + frequencyDensity2 INTEGER (1..276), + timeDensity1 INTEGER (0..29), + timeDensity2 INTEGER (0..29), + timeDensity3 INTEGER (0..29) +} + +PTRS-DensityRecommendationUL ::= SEQUENCE { + frequencyDensity1 INTEGER (1..276), + frequencyDensity2 INTEGER (1..276), + timeDensity1 INTEGER (0..29), + timeDensity2 INTEGER (0..29), + timeDensity3 INTEGER (0..29), + sampleDensity1 INTEGER (1..276), + sampleDensity2 INTEGER (1..276), + sampleDensity3 INTEGER (1..276), + sampleDensity4 INTEGER (1..276), + sampleDensity5 INTEGER (1..276) +} + +SpatialRelations ::= SEQUENCE { + maxNumberConfiguredSpatialRelations ENUMERATED {n4, n8, n16, n32, n64, n96}, + maxNumberActiveSpatialRelations ENUMERATED {n1, n2, n4, n8, n14}, + additionalActiveSpatialRelationPUCCH ENUMERATED {supported} OPTIONAL, + maxNumberDL-RS-QCL-TypeD ENUMERATED {n1, n2, n4, n8, n14} +} + +DummyI ::= SEQUENCE { + supportedSRS-TxPortSwitch ENUMERATED {t1r2, t1r4, t2r4, t1r4-t2r4, tr-equal}, + txSwitchImpactToRx ENUMERATED {true} OPTIONAL +} + +-- TAG-MIMO-PARAMETERSPERBAND-STOP +-- TAG-MODULATIONORDER-START + +ModulationOrder ::= ENUMERATED {bpsk-halfpi, bpsk, qpsk, qam16, qam64, qam256} + +-- TAG-MODULATIONORDER-STOP +-- TAG-MRDC-PARAMETERS-START + +MRDC-Parameters ::= SEQUENCE { + singleUL-Transmission ENUMERATED {supported} OPTIONAL, + dynamicPowerSharingENDC ENUMERATED {supported} OPTIONAL, + tdm-Pattern ENUMERATED {supported} OPTIONAL, + ul-SharingEUTRA-NR ENUMERATED {tdm, fdm, both} OPTIONAL, + ul-SwitchingTimeEUTRA-NR ENUMERATED {type1, type2} OPTIONAL, + simultaneousRxTxInterBandENDC ENUMERATED {supported} OPTIONAL, + asyncIntraBandENDC ENUMERATED {supported} OPTIONAL, + ..., + [[ + dualPA-Architecture ENUMERATED {supported} OPTIONAL, + intraBandENDC-Support ENUMERATED {non-contiguous, both} OPTIONAL, + ul-TimingAlignmentEUTRA-NR ENUMERATED {required} OPTIONAL + ]], + [[ + maxUplinkDutyCycle-interBandENDC-TDD-PC2-r16 SEQUENCE{ + eutra-TDD-Config0-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL, + eutra-TDD-Config1-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL, + eutra-TDD-Config2-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL, + eutra-TDD-Config3-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL, + eutra-TDD-Config4-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL, + eutra-TDD-Config5-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL, + eutra-TDD-Config6-r16 ENUMERATED {n20, n40, n50, n60, n70, n80, n90, n100} OPTIONAL + } OPTIONAL + ]] +} + +MRDC-Parameters-v1580 ::= SEQUENCE { + dynamicPowerSharingNEDC ENUMERATED {supported} OPTIONAL +} + +MRDC-Parameters-v1590 ::= SEQUENCE { + interBandContiguousMRDC ENUMERATED {supported} OPTIONAL +} + +-- TAG-MRDC-PARAMETERS-STOP +-- TAG-NRDC-PARAMETERS-START + +NRDC-Parameters ::= SEQUENCE { + measAndMobParametersNRDC MeasAndMobParametersMRDC OPTIONAL, + generalParametersNRDC GeneralParametersMRDC-XDD-Diff OPTIONAL, + fdd-Add-UE-NRDC-Capabilities UE-MRDC-CapabilityAddXDD-Mode OPTIONAL, + tdd-Add-UE-NRDC-Capabilities UE-MRDC-CapabilityAddXDD-Mode OPTIONAL, + fr1-Add-UE-NRDC-Capabilities UE-MRDC-CapabilityAddFRX-Mode OPTIONAL, + fr2-Add-UE-NRDC-Capabilities UE-MRDC-CapabilityAddFRX-Mode OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + dummy SEQUENCE {} OPTIONAL +} + +NRDC-Parameters-v1570 ::= SEQUENCE { + sfn-SyncNRDC ENUMERATED {supported} OPTIONAL +} + +NRDC-Parameters-v1610 ::= SEQUENCE { + measAndMobParametersNRDC-v1610 MeasAndMobParametersMRDC-v1610 OPTIONAL +} + + +-- TAG-NRDC-PARAMETERS-STOP +-- TAG-OLPC-SRS-POS-START + +OLPC-SRS-Pos-r16 ::= SEQUENCE { + olpc-SRS-PosBasedOnPRS-Serving-r16 ENUMERATED {supported} OPTIONAL, + olpc-SRS-PosBasedOnSSB-Neigh-r16 ENUMERATED {supported} OPTIONAL, + olpc-SRS-PosBasedOnPRS-Neigh-r16 ENUMERATED {supported} OPTIONAL, + maxNumberPathLossEstimatePerServing-r16 ENUMERATED {n1, n4, n8, n16} OPTIONAL +} + +--TAG-OLPC-SRS-POS-STOP +-- TAG-PDCP-PARAMETERS-START + +PDCP-Parameters ::= SEQUENCE { + supportedROHC-Profiles SEQUENCE { + profile0x0000 BOOLEAN, + profile0x0001 BOOLEAN, + profile0x0002 BOOLEAN, + profile0x0003 BOOLEAN, + profile0x0004 BOOLEAN, + profile0x0006 BOOLEAN, + profile0x0101 BOOLEAN, + profile0x0102 BOOLEAN, + profile0x0103 BOOLEAN, + profile0x0104 BOOLEAN + }, + maxNumberROHC-ContextSessions ENUMERATED {cs2, cs4, cs8, cs12, cs16, cs24, cs32, cs48, cs64, + cs128, cs256, cs512, cs1024, cs16384, spare2, spare1}, + uplinkOnlyROHC-Profiles ENUMERATED {supported} OPTIONAL, + continueROHC-Context ENUMERATED {supported} OPTIONAL, + outOfOrderDelivery ENUMERATED {supported} OPTIONAL, + shortSN ENUMERATED {supported} OPTIONAL, + pdcp-DuplicationSRB ENUMERATED {supported} OPTIONAL, + pdcp-DuplicationMCG-OrSCG-DRB ENUMERATED {supported} OPTIONAL, + ..., + [[ + drb-IAB-r16 ENUMERATED {supported} OPTIONAL, + non-DRB-IAB-r16 ENUMERATED {supported} OPTIONAL, + extendedDiscardTimer-r16 ENUMERATED {supported} OPTIONAL, + continueEHC-Context-r16 ENUMERATED {supported} OPTIONAL, + ehc-r16 ENUMERATED {supported} OPTIONAL, + maxNumberEHC-Contexts-r16 ENUMERATED {cs2, cs4, cs8, cs16, cs32, cs64, cs128, cs256, cs512, + cs1024, cs2048, cs4096, cs8192, cs16384, cs32768, cs65536} OPTIONAL, + jointEHC-ROHC-Config-r16 ENUMERATED {supported} OPTIONAL, + pdcp-DuplicationMoreThanTwoRLC-r16 ENUMERATED {supported} OPTIONAL + ]] +} + +-- TAG-PDCP-PARAMETERS-STOP +-- TAG-PDCP-PARAMETERSMRDC-START + +PDCP-ParametersMRDC ::= SEQUENCE { + pdcp-DuplicationSplitSRB ENUMERATED {supported} OPTIONAL, + pdcp-DuplicationSplitDRB ENUMERATED {supported} OPTIONAL +} + +PDCP-ParametersMRDC-v1610 ::= SEQUENCE { + scg-DRB-NR-IAB-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-PDCP-PARAMETERSMRDC-STOP +-- TAG-PHY-PARAMETERS-START + +Phy-Parameters ::= SEQUENCE { + phy-ParametersCommon Phy-ParametersCommon OPTIONAL, + phy-ParametersXDD-Diff Phy-ParametersXDD-Diff OPTIONAL, + phy-ParametersFRX-Diff Phy-ParametersFRX-Diff OPTIONAL, + phy-ParametersFR1 Phy-ParametersFR1 OPTIONAL, + phy-ParametersFR2 Phy-ParametersFR2 OPTIONAL +} + +Phy-ParametersCommon ::= SEQUENCE { + csi-RS-CFRA-ForHO ENUMERATED {supported} OPTIONAL, + dynamicPRB-BundlingDL ENUMERATED {supported} OPTIONAL, + sp-CSI-ReportPUCCH ENUMERATED {supported} OPTIONAL, + sp-CSI-ReportPUSCH ENUMERATED {supported} OPTIONAL, + nzp-CSI-RS-IntefMgmt ENUMERATED {supported} OPTIONAL, + type2-SP-CSI-Feedback-LongPUCCH ENUMERATED {supported} OPTIONAL, + precoderGranularityCORESET ENUMERATED {supported} OPTIONAL, + dynamicHARQ-ACK-Codebook ENUMERATED {supported} OPTIONAL, + semiStaticHARQ-ACK-Codebook ENUMERATED {supported} OPTIONAL, + spatialBundlingHARQ-ACK ENUMERATED {supported} OPTIONAL, + dynamicBetaOffsetInd-HARQ-ACK-CSI ENUMERATED {supported} OPTIONAL, + pucch-Repetition-F1-3-4 ENUMERATED {supported} OPTIONAL, + ra-Type0-PUSCH ENUMERATED {supported} OPTIONAL, + dynamicSwitchRA-Type0-1-PDSCH ENUMERATED {supported} OPTIONAL, + dynamicSwitchRA-Type0-1-PUSCH ENUMERATED {supported} OPTIONAL, + pdsch-MappingTypeA ENUMERATED {supported} OPTIONAL, + pdsch-MappingTypeB ENUMERATED {supported} OPTIONAL, + interleavingVRB-ToPRB-PDSCH ENUMERATED {supported} OPTIONAL, + interSlotFreqHopping-PUSCH ENUMERATED {supported} OPTIONAL, + type1-PUSCH-RepetitionMultiSlots ENUMERATED {supported} OPTIONAL, + type2-PUSCH-RepetitionMultiSlots ENUMERATED {supported} OPTIONAL, + pusch-RepetitionMultiSlots ENUMERATED {supported} OPTIONAL, + pdsch-RepetitionMultiSlots ENUMERATED {supported} OPTIONAL, + downlinkSPS ENUMERATED {supported} OPTIONAL, + configuredUL-GrantType1 ENUMERATED {supported} OPTIONAL, + configuredUL-GrantType2 ENUMERATED {supported} OPTIONAL, + pre-EmptIndication-DL ENUMERATED {supported} OPTIONAL, + cbg-TransIndication-DL ENUMERATED {supported} OPTIONAL, + cbg-TransIndication-UL ENUMERATED {supported} OPTIONAL, + cbg-FlushIndication-DL ENUMERATED {supported} OPTIONAL, + dynamicHARQ-ACK-CodeB-CBG-Retx-DL ENUMERATED {supported} OPTIONAL, + rateMatchingResrcSetSemi-Static ENUMERATED {supported} OPTIONAL, + rateMatchingResrcSetDynamic ENUMERATED {supported} OPTIONAL, + bwp-SwitchingDelay ENUMERATED {type1, type2} OPTIONAL, + ..., + [[ + dummy ENUMERATED {supported} OPTIONAL + ]], + [[ + maxNumberSearchSpaces ENUMERATED {n10} OPTIONAL, + rateMatchingCtrlResrcSetDynamic ENUMERATED {supported} OPTIONAL, + maxLayersMIMO-Indication ENUMERATED {supported} OPTIONAL + ]], + [[ + spCellPlacement CarrierAggregationVariant OPTIONAL + ]], + [[ + -- R1 9-1: Basic channel structure and procedure of 2-step RACH + twoStepRACH-r16 ENUMERATED {supported} OPTIONAL, + -- R1 11-1: Monitoring DCI format 1_2 and DCI format 0_2 + dci-Format1-2And0-2-r16 ENUMERATED {supported} OPTIONAL, + -- R1 11-1a: Monitoring both DCI format 0_1/1_1 and DCI format 0_2/1_2 in the same search space + monitoringDCI-SameSearchSpace-r16 ENUMERATED {supported} OPTIONAL, + -- R1 11-10: Type 2 configured grant release by DCI format 0_1 + type2-CG-ReleaseDCI-0-1-r16 ENUMERATED {supported} OPTIONAL, + -- R1 11-11: Type 2 configured grant release by DCI format 0_2 + type2-CG-ReleaseDCI-0-2-r16 ENUMERATED {supported} OPTIONAL, + -- R1 12-3: SPS release by DCI format 1_1 + sps-ReleaseDCI-1-1-r16 ENUMERATED {supported} OPTIONAL, + -- R1 12-3a: SPS release by DCI format 1_2 + sps-ReleaseDCI-1-2-r16 ENUMERATED {supported} OPTIONAL, + -- R1 14-8: CSI trigger states containing non-active BWP + csi-TriggerStateNon-ActiveBWP-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-2: Support up to 4 SMTCs configured for an IAB node MT per frequency location, including IAB-specific SMTC window periodicities + seperateSMTC-InterIAB-Support-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-3: Support RACH configuration separately from the RACH configuration for UE access, including new IAB-specific offset and scaling factors + seperateRACH-IAB-Support-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-5a: Support semi-static configuration/indication of UL-Flexible-DL slot formats for IAB-MT resources + ul-flexibleDL-SlotFormatSemiStatic-IAB-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-5b: Support dynamic indication of UL-Flexible-DL slot formats for IAB-MT resources + ul-flexibleDL-SlotFormatDynamics-IAB-r16 ENUMERATED {supported} OPTIONAL, + dft-S-OFDM-WaveformUL-IAB-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-6: Support DCI Format 2_5 based indication of soft resource availability to an IAB node + dci-25-AI-RNTI-Support-IAB-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-7: Support T_delta reception. + t-DeltaReceptionSupport-IAB-r16 ENUMERATED {supported} OPTIONAL, + -- R1 20-8: Support of Desired guard symbol reporting and provided guard symbok reception. + guardSymbolReportReception-IAB-r16 ENUMERATED {supported} OPTIONAL, + -- R1 18-8 HARQ-ACK codebook type and spatial bundling per PUCCH group + harqACK-CB-SpatialBundlingPUCCH-Group-r16 ENUMERATED {supported} OPTIONAL, + -- R1 19-2: Cross Slot Scheduling + crossSlotScheduling-r16 SEQUENCE { + licensedBand-r16 ENUMERATED {supported} OPTIONAL, + unlicensedBand-r16 ENUMERATED {supported} OPTIONAL + } OPTIONAL, + maxNumberSRS-PosPathLossEstimateAllServingCells-r16 ENUMERATED {n1, n4, n8, n16} OPTIONAL, + maxNumberSRS-PosSpatialRelationsAllServingCells-r16 ENUMERATED {n0, n1, n2, n4, n8, n16} OPTIONAL, + extendedCG-Periodicities-r16 ENUMERATED {supported} OPTIONAL, + extendedSPS-Periodicities-r16 ENUMERATED {supported} OPTIONAL, + codebookVariantsList-r16 CodebookVariantsList-r16 OPTIONAL + ]] +} + +Phy-ParametersXDD-Diff ::= SEQUENCE { + dynamicSFI ENUMERATED {supported} OPTIONAL, + twoPUCCH-F0-2-ConsecSymbols ENUMERATED {supported} OPTIONAL, + twoDifferentTPC-Loop-PUSCH ENUMERATED {supported} OPTIONAL, + twoDifferentTPC-Loop-PUCCH ENUMERATED {supported} OPTIONAL, + ..., + [[ + dl-SchedulingOffset-PDSCH-TypeA ENUMERATED {supported} OPTIONAL, + dl-SchedulingOffset-PDSCH-TypeB ENUMERATED {supported} OPTIONAL, + ul-SchedulingOffset ENUMERATED {supported} OPTIONAL + ]] +} + +Phy-ParametersFRX-Diff ::= SEQUENCE { + dynamicSFI ENUMERATED {supported} OPTIONAL, + dummy1 BIT STRING (SIZE (2)) OPTIONAL, + twoFL-DMRS BIT STRING (SIZE (2)) OPTIONAL, + dummy2 BIT STRING (SIZE (2)) OPTIONAL, + dummy3 BIT STRING (SIZE (2)) OPTIONAL, + supportedDMRS-TypeDL ENUMERATED {type1, type1And2} OPTIONAL, + supportedDMRS-TypeUL ENUMERATED {type1, type1And2} OPTIONAL, + semiOpenLoopCSI ENUMERATED {supported} OPTIONAL, + csi-ReportWithoutPMI ENUMERATED {supported} OPTIONAL, + csi-ReportWithoutCQI ENUMERATED {supported} OPTIONAL, + onePortsPTRS BIT STRING (SIZE (2)) OPTIONAL, + twoPUCCH-F0-2-ConsecSymbols ENUMERATED {supported} OPTIONAL, + pucch-F2-WithFH ENUMERATED {supported} OPTIONAL, + pucch-F3-WithFH ENUMERATED {supported} OPTIONAL, + pucch-F4-WithFH ENUMERATED {supported} OPTIONAL, + pucch-F0-2WithoutFH ENUMERATED {notSupported} OPTIONAL, + pucch-F1-3-4WithoutFH ENUMERATED {notSupported} OPTIONAL, + mux-SR-HARQ-ACK-CSI-PUCCH-MultiPerSlot ENUMERATED {supported} OPTIONAL, + uci-CodeBlockSegmentation ENUMERATED {supported} OPTIONAL, + onePUCCH-LongAndShortFormat ENUMERATED {supported} OPTIONAL, + twoPUCCH-AnyOthersInSlot ENUMERATED {supported} OPTIONAL, + intraSlotFreqHopping-PUSCH ENUMERATED {supported} OPTIONAL, + pusch-LBRM ENUMERATED {supported} OPTIONAL, + pdcch-BlindDetectionCA INTEGER (4..16) OPTIONAL, + tpc-PUSCH-RNTI ENUMERATED {supported} OPTIONAL, + tpc-PUCCH-RNTI ENUMERATED {supported} OPTIONAL, + tpc-SRS-RNTI ENUMERATED {supported} OPTIONAL, + absoluteTPC-Command ENUMERATED {supported} OPTIONAL, + twoDifferentTPC-Loop-PUSCH ENUMERATED {supported} OPTIONAL, + twoDifferentTPC-Loop-PUCCH ENUMERATED {supported} OPTIONAL, + pusch-HalfPi-BPSK ENUMERATED {supported} OPTIONAL, + pucch-F3-4-HalfPi-BPSK ENUMERATED {supported} OPTIONAL, + almostContiguousCP-OFDM-UL ENUMERATED {supported} OPTIONAL, + sp-CSI-RS ENUMERATED {supported} OPTIONAL, + sp-CSI-IM ENUMERATED {supported} OPTIONAL, + tdd-MultiDL-UL-SwitchPerSlot ENUMERATED {supported} OPTIONAL, + multipleCORESET ENUMERATED {supported} OPTIONAL, + ..., + [[ + csi-RS-IM-ReceptionForFeedback CSI-RS-IM-ReceptionForFeedback OPTIONAL, + csi-RS-ProcFrameworkForSRS CSI-RS-ProcFrameworkForSRS OPTIONAL, + csi-ReportFramework CSI-ReportFramework OPTIONAL, + mux-SR-HARQ-ACK-CSI-PUCCH-OncePerSlot SEQUENCE { + sameSymbol ENUMERATED {supported} OPTIONAL, + diffSymbol ENUMERATED {supported} OPTIONAL + } OPTIONAL, + mux-SR-HARQ-ACK-PUCCH ENUMERATED {supported} OPTIONAL, + mux-MultipleGroupCtrlCH-Overlap ENUMERATED {supported} OPTIONAL, + dl-SchedulingOffset-PDSCH-TypeA ENUMERATED {supported} OPTIONAL, + dl-SchedulingOffset-PDSCH-TypeB ENUMERATED {supported} OPTIONAL, + ul-SchedulingOffset ENUMERATED {supported} OPTIONAL, + dl-64QAM-MCS-TableAlt ENUMERATED {supported} OPTIONAL, + ul-64QAM-MCS-TableAlt ENUMERATED {supported} OPTIONAL, + cqi-TableAlt ENUMERATED {supported} OPTIONAL, + oneFL-DMRS-TwoAdditionalDMRS-UL ENUMERATED {supported} OPTIONAL, + twoFL-DMRS-TwoAdditionalDMRS-UL ENUMERATED {supported} OPTIONAL, + oneFL-DMRS-ThreeAdditionalDMRS-UL ENUMERATED {supported} OPTIONAL + ]], + [[ + pdcch-BlindDetectionNRDC SEQUENCE { + pdcch-BlindDetectionMCG-UE INTEGER (1..15), + pdcch-BlindDetectionSCG-UE INTEGER (1..15) + } OPTIONAL, + mux-HARQ-ACK-PUSCH-DiffSymbol ENUMERATED {supported} OPTIONAL + ]], + [[ + -- R1 11-1b: Type 1 HARQ-ACK codebook support for relative TDRA for DL + type1-HARQ-ACK-Codebook-r16 ENUMERATED {supported} OPTIONAL, + -- R1 11-8: Enhanced UL power control scheme + enhancedPowerControl-r16 ENUMERATED {supported} OPTIONAL, + -- R1 16-1b-1: TCI state activation across multiple CCs + simultaneousTCI-ActMultipleCC-r16 ENUMERATED {supported} OPTIONAL, + -- R1 16-1b-2: Spatial relation update across multiple CCs + simultaneousSpatialRelationMultipleCC-r16 ENUMERATED {supported} OPTIONAL, + -- R1 16-1c: Support of default spatial relation and pathloss reference RS for dedicated-PUCCH/SRS and PUSCH + defaultSpatialRelationPathlossRS-r16 ENUMERATED {supported} OPTIONAL, + -- R1 16-1d: Support of spatial relation update for AP-SRS via MAC CE + spatialRelationUpdateAP-SRS-r16 ENUMERATED {supported} OPTIONAL, + cli-RSSI-FDM-DL-r16 ENUMERATED {supported} OPTIONAL, + cli-SRS-RSRP-FDM-DL-r16 ENUMERATED {supported} OPTIONAL, + -- R1 19-3: Maximum MIMO Layer Adaptation + maxLayersMIMO-Adaptation-r16 ENUMERATED {supported} OPTIONAL + ]] + +} + +Phy-ParametersFR1 ::= SEQUENCE { + pdcch-MonitoringSingleOccasion ENUMERATED {supported} OPTIONAL, + scs-60kHz ENUMERATED {supported} OPTIONAL, + pdsch-256QAM-FR1 ENUMERATED {supported} OPTIONAL, + pdsch-RE-MappingFR1-PerSymbol ENUMERATED {n10, n20} OPTIONAL, + ..., + [[ + pdsch-RE-MappingFR1-PerSlot ENUMERATED {n16, n32, n48, n64, n80, n96, n112, n128, + n144, n160, n176, n192, n208, n224, n240, n256} OPTIONAL + ]] +} + +Phy-ParametersFR2 ::= SEQUENCE { + dummy ENUMERATED {supported} OPTIONAL, + pdsch-RE-MappingFR2-PerSymbol ENUMERATED {n6, n20} OPTIONAL, + ..., + [[ + pCell-FR2 ENUMERATED {supported} OPTIONAL, + pdsch-RE-MappingFR2-PerSlot ENUMERATED {n16, n32, n48, n64, n80, n96, n112, n128, + n144, n160, n176, n192, n208, n224, n240, n256} OPTIONAL + ]] +} + +-- TAG-PHY-PARAMETERS-STOP +-- TAG-PHY-PARAMETERSMRDC-START + +Phy-ParametersMRDC ::= SEQUENCE { + naics-Capability-List SEQUENCE (SIZE (1..maxNrofNAICS-Entries)) OF NAICS-Capability-Entry OPTIONAL, + ..., + [[ + spCellPlacement CarrierAggregationVariant OPTIONAL + ]] +} + +NAICS-Capability-Entry ::= SEQUENCE { + numberOfNAICS-CapableCC INTEGER(1..5), + numberOfAggregatedPRB ENUMERATED {n50, n75, n100, n125, n150, n175, n200, n225, + n250, n275, n300, n350, n400, n450, n500, spare}, + ... +} + +-- TAG-PHY-PARAMETERSMRDC-STOP +-- TAG-POWSAV-PARAMETERS-START + +PowSav-Parameters-r16 ::= SEQUENCE { + powSav-ParametersCommon-r16 PowSav-ParametersCommon-r16 OPTIONAL, + powSav-ParametersFRX-Diff-r16 PowSav-ParametersFRX-Diff-r16 OPTIONAL, + ... +} + +PowSav-ParametersCommon-r16 ::= SEQUENCE { + drx-Preference-r16 ENUMERATED {supported} OPTIONAL, + maxCC-Preference-r16 ENUMERATED {supported} OPTIONAL, + releasePreference-r16 ENUMERATED {supported} OPTIONAL, + -- R1 19-4a: UE assistance information + minSchedulingOffsetPreference-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +PowSav-ParametersFRX-Diff-r16 ::= SEQUENCE { + maxBW-Preference-r16 ENUMERATED {supported} OPTIONAL, + maxMIMO-LayerPreference-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +-- TAG-POWSAV-PARAMETERS-STOP +-- TAG-PROCESSINGPARAMETERS-START + +ProcessingParameters ::= SEQUENCE { + fallback ENUMERATED {sc, cap1-only}, + differentTB-PerSlot SEQUENCE { + upto1 NumberOfCarriers OPTIONAL, + upto2 NumberOfCarriers OPTIONAL, + upto4 NumberOfCarriers OPTIONAL, + upto7 NumberOfCarriers OPTIONAL + } OPTIONAL +} + +NumberOfCarriers ::= INTEGER (1..16) + +-- TAG-PROCESSINGPARAMETERS-STOP +-- TAG-RAT-TYPE-START + +RAT-Type ::= ENUMERATED {nr, eutra-nr, eutra, utra-fdd-v1610, ...} + +-- TAG-RAT-TYPE-STOP +-- TAG-RF-PARAMETERS-START + +RF-Parameters ::= SEQUENCE { + supportedBandListNR SEQUENCE (SIZE (1..maxBands)) OF BandNR, + supportedBandCombinationList BandCombinationList OPTIONAL, + appliedFreqBandListFilter FreqBandList OPTIONAL, + ..., + [[ + supportedBandCombinationList-v1540 BandCombinationList-v1540 OPTIONAL, + srs-SwitchingTimeRequested ENUMERATED {true} OPTIONAL + ]], + [[ + supportedBandCombinationList-v1550 BandCombinationList-v1550 OPTIONAL + ]], + [[ + supportedBandCombinationList-v1560 BandCombinationList-v1560 OPTIONAL + ]], + [[ + supportedBandCombinationList-v1610 BandCombinationList-v1610 OPTIONAL, + supportedBandCombinationListSidelink-r16 BandCombinationListSidelink-r16 OPTIONAL, + supportedBandCombinationList-UplinkTxSwitch-r16 BandCombinationList-UplinkTxSwitch-r16 OPTIONAL + ]] +} + +BandNR ::= SEQUENCE { + bandNR FreqBandIndicatorNR, + modifiedMPR-Behaviour BIT STRING (SIZE (8)) OPTIONAL, + mimo-ParametersPerBand MIMO-ParametersPerBand OPTIONAL, + extendedCP ENUMERATED {supported} OPTIONAL, + multipleTCI ENUMERATED {supported} OPTIONAL, + bwp-WithoutRestriction ENUMERATED {supported} OPTIONAL, + bwp-SameNumerology ENUMERATED {upto2, upto4} OPTIONAL, + bwp-DiffNumerology ENUMERATED {upto4} OPTIONAL, + crossCarrierScheduling-SameSCS ENUMERATED {supported} OPTIONAL, + pdsch-256QAM-FR2 ENUMERATED {supported} OPTIONAL, + pusch-256QAM ENUMERATED {supported} OPTIONAL, + ue-PowerClass ENUMERATED {pc1, pc2, pc3, pc4} OPTIONAL, + rateMatchingLTE-CRS ENUMERATED {supported} OPTIONAL, + channelBWs-DL CHOICE { + fr1 SEQUENCE { + scs-15kHz BIT STRING (SIZE (10)) OPTIONAL, + scs-30kHz BIT STRING (SIZE (10)) OPTIONAL, + scs-60kHz BIT STRING (SIZE (10)) OPTIONAL + }, + fr2 SEQUENCE { + scs-60kHz BIT STRING (SIZE (3)) OPTIONAL, + scs-120kHz BIT STRING (SIZE (3)) OPTIONAL + } + } OPTIONAL, + channelBWs-UL CHOICE { + fr1 SEQUENCE { + scs-15kHz BIT STRING (SIZE (10)) OPTIONAL, + scs-30kHz BIT STRING (SIZE (10)) OPTIONAL, + scs-60kHz BIT STRING (SIZE (10)) OPTIONAL + }, + fr2 SEQUENCE { + scs-60kHz BIT STRING (SIZE (3)) OPTIONAL, + scs-120kHz BIT STRING (SIZE (3)) OPTIONAL + } + } OPTIONAL, + ..., + [[ + maxUplinkDutyCycle-PC2-FR1 ENUMERATED {n60, n70, n80, n90, n100} OPTIONAL + ]], + [[ + pucch-SpatialRelInfoMAC-CE ENUMERATED {supported} OPTIONAL, + powerBoosting-pi2BPSK ENUMERATED {supported} OPTIONAL + ]], + [[ + maxUplinkDutyCycle-FR2 ENUMERATED {n15, n20, n25, n30, n40, n50, n60, n70, n80, n90, n100} OPTIONAL + ]], + [[ + channelBWs-DL-v1590 CHOICE { + fr1 SEQUENCE { + scs-15kHz BIT STRING (SIZE (16)) OPTIONAL, + scs-30kHz BIT STRING (SIZE (16)) OPTIONAL, + scs-60kHz BIT STRING (SIZE (16)) OPTIONAL + }, + fr2 SEQUENCE { + scs-60kHz BIT STRING (SIZE (8)) OPTIONAL, + scs-120kHz BIT STRING (SIZE (8)) OPTIONAL + } + } OPTIONAL, + channelBWs-UL-v1590 CHOICE { + fr1 SEQUENCE { + scs-15kHz BIT STRING (SIZE (16)) OPTIONAL, + scs-30kHz BIT STRING (SIZE (16)) OPTIONAL, + scs-60kHz BIT STRING (SIZE (16)) OPTIONAL + }, + fr2 SEQUENCE { + scs-60kHz BIT STRING (SIZE (8)) OPTIONAL, + scs-120kHz BIT STRING (SIZE (8)) OPTIONAL + } + } OPTIONAL + ]], + [[ + asymmetricBandwidthCombinationSet BIT STRING (SIZE (1..32)) OPTIONAL + ]], + [[ + -- R1 10: NR-unlicensed + unlicensedParametersPerBand-r16 UnlicensedParametersPerBand-r16 OPTIONAL, + -- R1 11-7b: Independent cancellation of the overlapping PUSCHs in an intra-band UL CA + cancelOverlappingPUSCH-r16 ENUMERATED {supported} OPTIONAL, + -- R1 14-1: Multiple LTE-CRS rate matching patterns + multipleRateMatchingEUTRA-CRS-r16 SEQUENCE { + maxNumberPatterns-r16 INTEGER (2..6), + maxNumberNon-OverlapPatterns-r16 INTEGER (1..3) + } OPTIONAL, + -- R1 14-1a: Two LTE-CRS overlapping rate matching patterns within a part of NR carrier using 15 kHz overlapping with a LTE carrier + overlapRateMatchingEUTRA-CRS-r16 ENUMERATED {supported} OPTIONAL, + -- R1 14-2: PDSCH Type B mapping of length 9 and 10 OFDM symbols + pdsch-MappingTypeB-Alt-r16 ENUMERATED {supported} OPTIONAL, + -- R1 14-3: One slot periodic TRS configuration for FR1 + oneShotPeriodicTRS-r16 ENUMERATED {supported} OPTIONAL, + olpc-SRS-Pos-r16 OLPC-SRS-Pos-r16 OPTIONAL, + spatialRelationsSRS-Pos-r16 SpatialRelationsSRS-Pos-r16 OPTIONAL, + simul-SRS-Trans-IntraBandCA-r16 INTEGER (1..2) OPTIONAL, + channelBW-DL-IAB-r16 CHOICE { + fr1-100mhz SEQUENCE { + scs-15kHz ENUMERATED {supported} OPTIONAL, + scs-30kHz ENUMERATED {supported} OPTIONAL, + scs-60kHz ENUMERATED {supported} OPTIONAL + }, + fr2-200mhz SEQUENCE { + scs-60kHz ENUMERATED {supported} OPTIONAL, + scs-120kHz ENUMERATED {supported} OPTIONAL + } + } OPTIONAL, + channelBW-UL-IAB-r16 CHOICE { + fr1-100mhz SEQUENCE { + scs-15kHz ENUMERATED {supported} OPTIONAL, + scs-30kHz ENUMERATED {supported} OPTIONAL, + scs-60kHz ENUMERATED {supported} OPTIONAL + }, + fr2-200mhz SEQUENCE { + scs-60kHz ENUMERATED {supported} OPTIONAL, + scs-120kHz ENUMERATED {supported} OPTIONAL + } + } OPTIONAL, + rasterShift7dot5-IAB-r16 ENUMERATED {supported} OPTIONAL, + ue-PowerClass-v1610 ENUMERATED {pc1dot5} OPTIONAL + ]] +} + +-- TAG-RF-PARAMETERS-STOP +-- TAG-RF-PARAMETERSMRDC-START + +RF-ParametersMRDC ::= SEQUENCE { + supportedBandCombinationList BandCombinationList OPTIONAL, + appliedFreqBandListFilter FreqBandList OPTIONAL, + ..., + [[ + srs-SwitchingTimeRequested ENUMERATED {true} OPTIONAL, + supportedBandCombinationList-v1540 BandCombinationList-v1540 OPTIONAL + ]], + [[ + supportedBandCombinationList-v1550 BandCombinationList-v1550 OPTIONAL + ]], + [[ + supportedBandCombinationList-v1560 BandCombinationList-v1560 OPTIONAL, + supportedBandCombinationListNEDC-Only BandCombinationList OPTIONAL + ]], + [[ + supportedBandCombinationList-v1570 BandCombinationList-v1570 OPTIONAL + ]], + [[ + supportedBandCombinationList-v1580 BandCombinationList-v1580 OPTIONAL + ]], + [[ + supportedBandCombinationList-v1590 BandCombinationList-v1590 OPTIONAL + ]], + [[ + supportedBandCombinationListNEDC-Only-v15a0 SEQUENCE { + supportedBandCombinationList-v1540 BandCombinationList-v1540 OPTIONAL, + supportedBandCombinationList-v1560 BandCombinationList-v1560 OPTIONAL, + supportedBandCombinationList-v1570 BandCombinationList-v1570 OPTIONAL, + supportedBandCombinationList-v1580 BandCombinationList-v1580 OPTIONAL, + supportedBandCombinationList-v1590 BandCombinationList-v1590 OPTIONAL + } OPTIONAL + ]], + [[ + supportedBandCombinationList-v1610 BandCombinationList-v1610 OPTIONAL, + supportedBandCombinationListNEDC-Only-v1610 BandCombinationList-v1610 OPTIONAL, + supportedBandCombinationList-UplinkTxSwitch-r16 BandCombinationList-UplinkTxSwitch-r16 OPTIONAL + ]] +} + +-- TAG-RF-PARAMETERSMRDC-STOP +-- TAG-RLC-PARAMETERS-START + +RLC-Parameters ::= SEQUENCE { + am-WithShortSN ENUMERATED {supported} OPTIONAL, + um-WithShortSN ENUMERATED {supported} OPTIONAL, + um-WithLongSN ENUMERATED {supported} OPTIONAL, + ..., + [[ + extendedT-PollRetransmit-r16 ENUMERATED {supported} OPTIONAL, + extendedT-StatusProhibit-r16 ENUMERATED {supported} OPTIONAL + ]] +} + +-- TAG-RLC-PARAMETERS-STOP +-- TAG-SDAP-PARAMETERS-START + +SDAP-Parameters ::= SEQUENCE { + as-ReflectiveQoS ENUMERATED {true} OPTIONAL, + ..., + [[ + sdap-QOS-IAB-r16 ENUMERATED {supported} OPTIONAL, + sdapHeaderIAB-r16 ENUMERATED {supported} OPTIONAL + ]] + +} + +-- TAG-SDAP-PARAMETERS-STOP +-- TAG-SIDELINKPARAMETERS-START + +SidelinkParameters-r16 ::= SEQUENCE { + sidelinkParametersNR-r16 SidelinkParametersNR-r16 OPTIONAL, + sidelinkParametersEUTRA-r16 SidelinkParametersEUTRA-r16 OPTIONAL +} + +SidelinkParametersNR-r16 ::= SEQUENCE { + rlc-ParametersSidelink-r16 RLC-ParametersSidelink-r16 OPTIONAL, + mac-ParametersSidelink-r16 MAC-ParametersSidelink-r16 OPTIONAL, + fdd-Add-UE-Sidelink-Capabilities-r16 UE-SidelinkCapabilityAddXDD-Mode-r16 OPTIONAL, + tdd-Add-UE-Sidelink-Capabilities-r16 UE-SidelinkCapabilityAddXDD-Mode-r16 OPTIONAL, + ... +} + +SidelinkParametersEUTRA-r16 ::= SEQUENCE { + sl-ParametersEUTRA1-r16 OCTET STRING OPTIONAL, + sl-ParametersEUTRA2-r16 OCTET STRING OPTIONAL, + sl-ParametersEUTRA3-r16 OCTET STRING OPTIONAL, + supportedBandListSidelinkEUTRA-r16 SEQUENCE (SIZE (1..maxBandsEUTRA)) OF BandSidelinkEUTRA-r16 OPTIONAL, + ... +} + +RLC-ParametersSidelink-r16 ::= SEQUENCE { + am-WithLongSN-Sidelink-r16 ENUMERATED {supported} OPTIONAL, + um-WithLongSN-Sidelink-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +MAC-ParametersSidelink-r16 ::= SEQUENCE { + mac-ParametersSidelinkCommon-r16 MAC-ParametersSidelinkCommon-r16 OPTIONAL, + mac-ParametersSidelinkXDD-Diff-r16 MAC-ParametersSidelinkXDD-Diff-r16 OPTIONAL, + ... +} + +UE-SidelinkCapabilityAddXDD-Mode-r16 ::= SEQUENCE { + mac-ParametersSidelinkXDD-Diff-r16 MAC-ParametersSidelinkXDD-Diff-r16 OPTIONAL +} + +MAC-ParametersSidelinkCommon-r16 ::= SEQUENCE { + lcp-RestrictionSidelink-r16 ENUMERATED {supported} OPTIONAL, + multipleConfiguredGrantsSidelink-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +MAC-ParametersSidelinkXDD-Diff-r16 ::= SEQUENCE { + multipleSR-ConfigurationsSidelink-r16 ENUMERATED {supported} OPTIONAL, + logicalChannelSR-DelayTimerSidelink-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +BandSidelinkEUTRA-r16 ::= SEQUENCE { + freqBandSidelinkEUTRA-r16 FreqBandIndicatorEUTRA, + -- R1 15-7: Transmitting LTE sidelink mode 3 scheduled by NR Uu + gnb-ScheduledMode3SidelinkEUTRA-r16 SEQUENCE { + gnb-ScheduledMode3DelaySidelinkEUTRA-r16 ENUMERATED {ms0, ms0dot25, ms0dot5, ms0dot625, ms0dot75, ms1, + ms1dot25, ms1dot5, ms1dot75, ms2, ms2dot5, ms3, ms4, + ms5, ms6, ms8, ms10, ms20} + } OPTIONAL, + -- R1 15-9: Transmitting LTE sidelink mode 4 configured by NR Uu + gnb-ScheduledMode4SidelinkEUTRA-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-SIDELINKPARAMETERS-STOP +-- TAG-SON-PARAMETERS-START + +SON-Parameters-r16 ::= SEQUENCE { + rach-Report-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +-- TAG-SON-PARAMETERS-STOP +-- TAG-SPATIALRELATIONSSRS-POS-START + +SpatialRelationsSRS-Pos-r16 ::= SEQUENCE { + spatialRelation-SRS-PosBasedOnSSB-Serving-r16 ENUMERATED {supported} OPTIONAL, + spatialRelation-SRS-PosBasedOnCSI-RS-Serving-r16 ENUMERATED {supported} OPTIONAL, + spatialRelation-SRS-PosBasedOnPRS-Serving-r16 ENUMERATED {supported} OPTIONAL, + spatialRelation-SRS-PosBasedOnSRS-r16 ENUMERATED {supported} OPTIONAL, + spatialRelation-SRS-PosBasedOnSSB-Neigh-r16 ENUMERATED {supported} OPTIONAL, + spatialRelation-SRS-PosBasedOnPRS-Neigh-r16 ENUMERATED {supported} OPTIONAL +} + +--TAG-SPATIALRELATIONSSRS-POS-STOP +-- TAG-SRS-SWITCHINGTIMENR-START + +SRS-SwitchingTimeNR ::= SEQUENCE { + switchingTimeDL ENUMERATED {n0us, n30us, n100us, n140us, n200us, n300us, n500us, n900us} OPTIONAL, + switchingTimeUL ENUMERATED {n0us, n30us, n100us, n140us, n200us, n300us, n500us, n900us} OPTIONAL +} + +-- TAG-SRS-SWITCHINGTIMENR-STOP +-- TAG-SRS-SWITCHINGTIMEEUTRA-START + +SRS-SwitchingTimeEUTRA ::= SEQUENCE { + switchingTimeDL ENUMERATED {n0, n0dot5, n1, n1dot5, n2, n2dot5, n3, n3dot5, n4, n4dot5, n5, n5dot5, n6, n6dot5, n7} + OPTIONAL, + switchingTimeUL ENUMERATED {n0, n0dot5, n1, n1dot5, n2, n2dot5, n3, n3dot5, n4, n4dot5, n5, n5dot5, n6, n6dot5, n7} + OPTIONAL +} +-- TAG-SRS-SWITCHINGTIMEEUTRA-STOP +-- TAG-SUPPORTEDBANDWIDTH-START + +SupportedBandwidth ::= CHOICE { + fr1 ENUMERATED {mhz5, mhz10, mhz15, mhz20, mhz25, mhz30, mhz40, mhz50, mhz60, mhz80, mhz100}, + fr2 ENUMERATED {mhz50, mhz100, mhz200, mhz400} +} + +-- TAG-SUPPORTEDBANDWIDTH-STOP +-- TAG-UE-BASEDPERFMEAS-PARAMETERS-START + +UE-BasedPerfMeas-Parameters-r16 ::= SEQUENCE { + barometerMeasReport-r16 ENUMERATED {supported} OPTIONAL, + immMeasBT-r16 ENUMERATED {supported} OPTIONAL, + immMeasWLAN-r16 ENUMERATED {supported} OPTIONAL, + loggedMeasBT-r16 ENUMERATED {supported} OPTIONAL, + loggedMeasurements-r16 ENUMERATED {supported} OPTIONAL, + loggedMeasWLAN-r16 ENUMERATED {supported} OPTIONAL, + orientationMeasReport-r16 ENUMERATED {supported} OPTIONAL, + speedMeasReport-r16 ENUMERATED {supported} OPTIONAL, + gnss-Location-r16 ENUMERATED {supported} OPTIONAL, + ulPDCP-Delay-r16 ENUMERATED {supported} OPTIONAL, + ... +} + +-- TAG-UE-BASEDPERFMEAS-PARAMETERS-STOP +-- TAG-UE-CAPABILITYRAT-CONTAINERLIST-START + +UE-CapabilityRAT-ContainerList ::= SEQUENCE (SIZE (0..maxRAT-CapabilityContainers)) OF UE-CapabilityRAT-Container + +UE-CapabilityRAT-Container ::= SEQUENCE { + rat-Type RAT-Type, + ue-CapabilityRAT-Container OCTET STRING +} + +-- TAG-UE-CAPABILITYRAT-CONTAINERLIST-STOP +-- TAG-UE-CAPABILITYRAT-REQUESTLIST-START + +UE-CapabilityRAT-RequestList ::= SEQUENCE (SIZE (1..maxRAT-CapabilityContainers)) OF UE-CapabilityRAT-Request + +UE-CapabilityRAT-Request ::= SEQUENCE { + rat-Type RAT-Type, + capabilityRequestFilter OCTET STRING OPTIONAL, -- Need N + ... +} + +-- TAG-UE-CAPABILITYRAT-REQUESTLIST-STOP +-- TAG-UE-CAPABILITYREQUESTFILTERCOMMON-START + +UE-CapabilityRequestFilterCommon ::= SEQUENCE { + mrdc-Request SEQUENCE { + omitEN-DC ENUMERATED {true} OPTIONAL, -- Need N + includeNR-DC ENUMERATED {true} OPTIONAL, -- Need N + includeNE-DC ENUMERATED {true} OPTIONAL -- Need N + } OPTIONAL, -- Need N + ..., + [[ + codebookTypeRequest-r16 SEQUENCE { + type1-SinglePanel-r16 ENUMERATED {true} OPTIONAL, -- Need N + type1-MultiPanel-r16 ENUMERATED {true} OPTIONAL, -- Need N + type2-r16 ENUMERATED {true} OPTIONAL, -- Need N + type2-PortSelection-r16 ENUMERATED {true} OPTIONAL -- Need N + } OPTIONAL, -- Need N + uplinkTxSwitchRequest-r16 ENUMERATED {true} OPTIONAL -- Need N + ]] +} + +-- TAG-UE-CAPABILITYREQUESTFILTERCOMMON-STOP +-- TAG-UE-CAPABILITYREQUESTFILTERNR-START + +UE-CapabilityRequestFilterNR ::= SEQUENCE { + frequencyBandListFilter FreqBandList OPTIONAL, -- Need N + nonCriticalExtension UE-CapabilityRequestFilterNR-v1540 OPTIONAL +} + +UE-CapabilityRequestFilterNR-v1540 ::= SEQUENCE { + srs-SwitchingTimeRequest ENUMERATED {true} OPTIONAL, -- Need N + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-UE-CAPABILITYREQUESTFILTERNR-STOP +-- TAG-UE-MRDC-CAPABILITY-START + +UE-MRDC-Capability ::= SEQUENCE { + measAndMobParametersMRDC MeasAndMobParametersMRDC OPTIONAL, + phy-ParametersMRDC-v1530 Phy-ParametersMRDC OPTIONAL, + rf-ParametersMRDC RF-ParametersMRDC, + generalParametersMRDC GeneralParametersMRDC-XDD-Diff OPTIONAL, + fdd-Add-UE-MRDC-Capabilities UE-MRDC-CapabilityAddXDD-Mode OPTIONAL, + tdd-Add-UE-MRDC-Capabilities UE-MRDC-CapabilityAddXDD-Mode OPTIONAL, + fr1-Add-UE-MRDC-Capabilities UE-MRDC-CapabilityAddFRX-Mode OPTIONAL, + fr2-Add-UE-MRDC-Capabilities UE-MRDC-CapabilityAddFRX-Mode OPTIONAL, + featureSetCombinations SEQUENCE (SIZE (1..maxFeatureSetCombinations)) OF FeatureSetCombination OPTIONAL, + pdcp-ParametersMRDC-v1530 PDCP-ParametersMRDC OPTIONAL, + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UE-MRDC-Capability-v1560 OPTIONAL +} + +UE-MRDC-Capability-v1560 ::= SEQUENCE { + receivedFilters OCTET STRING (CONTAINING UECapabilityEnquiry-v1560-IEs) OPTIONAL, + measAndMobParametersMRDC-v1560 MeasAndMobParametersMRDC-v1560 OPTIONAL, + fdd-Add-UE-MRDC-Capabilities-v1560 UE-MRDC-CapabilityAddXDD-Mode-v1560 OPTIONAL, + tdd-Add-UE-MRDC-Capabilities-v1560 UE-MRDC-CapabilityAddXDD-Mode-v1560 OPTIONAL, + nonCriticalExtension UE-MRDC-Capability-v1610 OPTIONAL +} + +UE-MRDC-Capability-v1610 ::= SEQUENCE { + measAndMobParametersMRDC-v1610 MeasAndMobParametersMRDC-v1610 OPTIONAL, + generalParametersMRDC-v1610 GeneralParametersMRDC-v1610 OPTIONAL, + pdcp-ParametersMRDC-v1610 PDCP-ParametersMRDC-v1610 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +UE-MRDC-CapabilityAddXDD-Mode ::= SEQUENCE { + measAndMobParametersMRDC-XDD-Diff MeasAndMobParametersMRDC-XDD-Diff OPTIONAL, + generalParametersMRDC-XDD-Diff GeneralParametersMRDC-XDD-Diff OPTIONAL +} + +UE-MRDC-CapabilityAddXDD-Mode-v1560 ::= SEQUENCE { + measAndMobParametersMRDC-XDD-Diff-v1560 MeasAndMobParametersMRDC-XDD-Diff-v1560 OPTIONAL +} + +UE-MRDC-CapabilityAddFRX-Mode ::= SEQUENCE { + measAndMobParametersMRDC-FRX-Diff MeasAndMobParametersMRDC-FRX-Diff +} + + +GeneralParametersMRDC-XDD-Diff ::= SEQUENCE { + splitSRB-WithOneUL-Path ENUMERATED {supported} OPTIONAL, + splitDRB-withUL-Both-MCG-SCG ENUMERATED {supported} OPTIONAL, + srb3 ENUMERATED {supported} OPTIONAL, + v2x-EUTRA ENUMERATED {supported} OPTIONAL, + ... +} + +GeneralParametersMRDC-v1610 ::= SEQUENCE { + f1c-OverEUTRA-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-UE-MRDC-CAPABILITY-STOP +-- TAG-UE-NR-CAPABILITY-START + +UE-NR-Capability ::= SEQUENCE { + accessStratumRelease AccessStratumRelease, + pdcp-Parameters PDCP-Parameters, + rlc-Parameters RLC-Parameters OPTIONAL, + mac-Parameters MAC-Parameters OPTIONAL, + phy-Parameters Phy-Parameters, + rf-Parameters RF-Parameters, + measAndMobParameters MeasAndMobParameters OPTIONAL, + fdd-Add-UE-NR-Capabilities UE-NR-CapabilityAddXDD-Mode OPTIONAL, + tdd-Add-UE-NR-Capabilities UE-NR-CapabilityAddXDD-Mode OPTIONAL, + fr1-Add-UE-NR-Capabilities UE-NR-CapabilityAddFRX-Mode OPTIONAL, + fr2-Add-UE-NR-Capabilities UE-NR-CapabilityAddFRX-Mode OPTIONAL, + featureSets FeatureSets OPTIONAL, + featureSetCombinations SEQUENCE (SIZE (1..maxFeatureSetCombinations)) OF FeatureSetCombination OPTIONAL, + + lateNonCriticalExtension OCTET STRING OPTIONAL, + nonCriticalExtension UE-NR-Capability-v1530 OPTIONAL +} + +UE-NR-Capability-v1530 ::= SEQUENCE { + fdd-Add-UE-NR-Capabilities-v1530 UE-NR-CapabilityAddXDD-Mode-v1530 OPTIONAL, + tdd-Add-UE-NR-Capabilities-v1530 UE-NR-CapabilityAddXDD-Mode-v1530 OPTIONAL, + dummy ENUMERATED {supported} OPTIONAL, + interRAT-Parameters InterRAT-Parameters OPTIONAL, + inactiveState ENUMERATED {supported} OPTIONAL, + delayBudgetReporting ENUMERATED {supported} OPTIONAL, + nonCriticalExtension UE-NR-Capability-v1540 OPTIONAL +} + +UE-NR-Capability-v1540 ::= SEQUENCE { + sdap-Parameters SDAP-Parameters OPTIONAL, + overheatingInd ENUMERATED {supported} OPTIONAL, + ims-Parameters IMS-Parameters OPTIONAL, + fr1-Add-UE-NR-Capabilities-v1540 UE-NR-CapabilityAddFRX-Mode-v1540 OPTIONAL, + fr2-Add-UE-NR-Capabilities-v1540 UE-NR-CapabilityAddFRX-Mode-v1540 OPTIONAL, + fr1-fr2-Add-UE-NR-Capabilities UE-NR-CapabilityAddFRX-Mode OPTIONAL, + nonCriticalExtension UE-NR-Capability-v1550 OPTIONAL +} + +UE-NR-Capability-v1550 ::= SEQUENCE { + reducedCP-Latency ENUMERATED {supported} OPTIONAL, + nonCriticalExtension UE-NR-Capability-v1560 OPTIONAL +} + +UE-NR-Capability-v1560 ::= SEQUENCE { + nrdc-Parameters NRDC-Parameters OPTIONAL, + receivedFilters OCTET STRING (CONTAINING UECapabilityEnquiry-v1560-IEs) OPTIONAL, + nonCriticalExtension UE-NR-Capability-v1570 OPTIONAL +} + +UE-NR-Capability-v1570 ::= SEQUENCE { + nrdc-Parameters-v1570 NRDC-Parameters-v1570 OPTIONAL, + nonCriticalExtension UE-NR-Capability-v1610 OPTIONAL +} + +UE-NR-Capability-v1610 ::= SEQUENCE { + inDeviceCoexInd-r16 ENUMERATED {supported} OPTIONAL, + dl-DedicatedMessageSegmentation-r16 ENUMERATED {supported} OPTIONAL, + nrdc-Parameters-v1610 NRDC-Parameters-v1610 OPTIONAL, + powSav-Parameters-r16 PowSav-Parameters-r16 OPTIONAL, + fr1-Add-UE-NR-Capabilities-v1610 UE-NR-CapabilityAddFRX-Mode-v1610 OPTIONAL, + fr2-Add-UE-NR-Capabilities-v1610 UE-NR-CapabilityAddFRX-Mode-v1610 OPTIONAL, + bh-RLF-Indication-r16 ENUMERATED {supported} OPTIONAL, + directSN-AdditionFirstRRC-IAB-r16 ENUMERATED {supported} OPTIONAL, + bap-Parameters-r16 BAP-Parameters-r16 OPTIONAL, + referenceTimeProvision-r16 ENUMERATED {supported} OPTIONAL, + sidelinkParameters-r16 SidelinkParameters-r16 OPTIONAL, + highSpeedParameters-r16 HighSpeedParameters-r16 OPTIONAL, + mac-Parameters-v1610 MAC-Parameters-v1610 OPTIONAL, + mcgRLF-RecoveryViaSCG-r16 ENUMERATED {supported} OPTIONAL, + resumeWithStoredMCG-SCells-r16 ENUMERATED {supported} OPTIONAL, + resumeWithStoredSCG-r16 ENUMERATED {supported} OPTIONAL, + resumeWithSCG-Config-r16 ENUMERATED {supported} OPTIONAL, + ue-BasedPerfMeas-Parameters-r16 UE-BasedPerfMeas-Parameters-r16 OPTIONAL, + son-Parameters-r16 SON-Parameters-r16 OPTIONAL, + onDemandSIB-Connected-r16 ENUMERATED {supported} OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +UE-NR-CapabilityAddXDD-Mode ::= SEQUENCE { + phy-ParametersXDD-Diff Phy-ParametersXDD-Diff OPTIONAL, + mac-ParametersXDD-Diff MAC-ParametersXDD-Diff OPTIONAL, + measAndMobParametersXDD-Diff MeasAndMobParametersXDD-Diff OPTIONAL +} + +UE-NR-CapabilityAddXDD-Mode-v1530 ::= SEQUENCE { + eutra-ParametersXDD-Diff EUTRA-ParametersXDD-Diff +} + +UE-NR-CapabilityAddFRX-Mode ::= SEQUENCE { + phy-ParametersFRX-Diff Phy-ParametersFRX-Diff OPTIONAL, + measAndMobParametersFRX-Diff MeasAndMobParametersFRX-Diff OPTIONAL +} + +UE-NR-CapabilityAddFRX-Mode-v1540 ::= SEQUENCE { + ims-ParametersFRX-Diff IMS-ParametersFRX-Diff OPTIONAL +} + +UE-NR-CapabilityAddFRX-Mode-v1610 ::= SEQUENCE { + powSav-ParametersFRX-Diff-r16 PowSav-ParametersFRX-Diff-r16 OPTIONAL, + mac-ParametersFRX-Diff-r16 MAC-ParametersFRX-Diff-r16 OPTIONAL +} + +BAP-Parameters-r16 ::= SEQUENCE { + flowControlBH-RLC-ChannelBased-r16 ENUMERATED {supported} OPTIONAL, + flowControlRouting-ID-Based-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-UE-NR-CAPABILITY-STOP +-- TAG-UNLICENSEDPARAMETERSPERBAND-START + +UnlicensedParametersPerBand-r16 ::= SEQUENCE { + -- R1 10-2g: SSB-based BFD/CBD for dynamic channel access mode + ssb-BFD-CBD-dynamicChannelAccess-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-2h: SSB-based BFD/CBD for semi-static channel access mode + ssb-BFD-CBD-semi-staticChannelAccess-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-2i: CSI-RS-based BFD/CBD for NR-U + csi-RS-BFD-CBD-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-10: RSSI and channel occupancy measurement and reporting + rssi-ChannelOccupancyReporting-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-11:SRS starting position at any OFDM symbol in a slot + srs-StartAnyOFDM-Symbol-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-20: Support search space set configuration with freqMonitorLocation-r16 + searchSpaceFreqMonitorLocation-r16 INTEGER (1..5) OPTIONAL, + -- R1 10-20a: Support coreset configuration with rb-Offset + coreset-RB-Offset-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-23:CGI reading on unlicensed cell for ANR functionality + cgi-Acquisition-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-25: Enable configured UL transmissions when DCI 2_0 is configured but not detected + configuredUL-Tx-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-8: Type B PDSCH length {3, 5, 6, 8, 9, 10, 11, 12, 13} without DMRS shift due to CRS collision + typeB-PDSCH-length-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-9: Search space set group switching with explicit DCI 2_0 bit field trigger or with implicit PDCCH decoding with DCI 2_0 monitoring + searchSpaceSetGroupSwitchingwithDCI-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-9b: Search space set group switching with implicit PDCCH decoding without DCI 2_0 monitoring FFS:per band or per UE + searchSpaceSetGroupSwitchingwithoutDCI-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-9d: Support Search space set group switching capability 2 + searchSpaceSetGroupSwitchingcapability2-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-14: Non-numerical PDSCH to HARQ-ACK timing + non-numericalPDSCH-HARQ-timing-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-15: Enhanced dynamic HARQ codebook + enhancedDynamicHARQ-codebook-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-16: One-shot HARQ ACK feedback + oneShotHARQ-feedback-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-17: Multi-PUSCH UL grant + multiPUSCH-UL-grant-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-26: CSI-RS based RLM for NR-U + csi-RS-RLM-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-26a: CSI-RS based RRM for NR-U + vcsi-RS-RRM-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-3: PRB interlace mapping for PUSCH + pusch-PRB-interlace-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-3a: PRB interlace mapping for PUCCH + pucch-F0-F1-PRB-Interlace-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-12: OCC for PRB interlace mapping for PF2 and PF3 + occ-PRB-PF2-PF3-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-13a: Extended CP range of more than one symbol for CG-PUSCH + extCP-rangeCG-PUSCH-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-18: Configured grant with retransmission in CG resources + configuredGrantWithReTx-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-24: CG-UCI multiplexing with HARQ ACK + mux-CG-UCI-HARQ-ACK-r16 ENUMERATED {supported} OPTIONAL, + -- R1 10-28: Configured grant with Rel-16 enhanced resource configuration + cg-resourceConfig-r16 ENUMERATED {supported} OPTIONAL +} + +-- TAG-UNLICENSEDPARAMETERSPERBAND-STOP +-- TAG-ABSOLUTETIMEINFO-START + +AbsoluteTimeInfo-r16 ::= BIT STRING (SIZE (48)) + +-- TAG-ABSOLUTETIMEINFO-STOP +-- TAG-AREACONFIGURATION-START + +AreaConfiguration-r16 ::= SEQUENCE { + areaConfig-r16 AreaConfig-r16, + interFreqTargetList-r16 SEQUENCE(SIZE (1..maxFreq)) OF InterFreqTargetInfo-r16 OPTIONAL -- Need R +} + +AreaConfig-r16 ::= CHOICE { + cellGlobalIdList-r16 CellGlobalIdList-r16, + trackingAreaCodeList-r16 TrackingAreaCodeList-r16, + trackingAreaIdentityList-r16 TrackingAreaIdentityList-r16 +} + +InterFreqTargetInfo-r16 ::= SEQUENCE { + dl-CarrierFreq ARFCN-ValueNR, + cellList SEQUENCE (SIZE (1..32)) OF PhysCellId OPTIONAL +} + +CellGlobalIdList-r16 ::= SEQUENCE (SIZE (1..32)) OF CGI-Info-Logging-r16 + +TrackingAreaCodeList-r16 ::= SEQUENCE (SIZE (1..8)) OF TrackingAreaCode + +TrackingAreaIdentityList-r16 ::= SEQUENCE (SIZE (1..8)) OF TrackingAreaIdentity-r16 + +TrackingAreaIdentity-r16 ::= SEQUENCE { + plmn-Identity-r16 PLMN-Identity, + trackingAreaCode-r16 TrackingAreaCode +} + +-- TAG-AREACONFIGURATION-STOP +-- TAG-BTNAMELIST-START + +BT-NameList-r16 ::= SEQUENCE (SIZE (1..maxBT-Name-r16)) OF BT-Name-r16 + +BT-Name-r16 ::= OCTET STRING (SIZE (1..248)) + +-- TAG-BTNAMELIST-STOP +-- TAG-EUTRA-ALLOWEDMEASBANDWIDTH-START + +EUTRA-AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100} + +-- TAG-EUTRA-ALLOWEDMEASBANDWIDTH-STOP +-- TAG-EUTRA-MBSFN-SUBFRAMECONFIGLIST-START + +EUTRA-MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF EUTRA-MBSFN-SubframeConfig + +EUTRA-MBSFN-SubframeConfig ::= SEQUENCE { + radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32}, + radioframeAllocationOffset INTEGER (0..7), + subframeAllocation1 CHOICE { + oneFrame BIT STRING (SIZE(6)), + fourFrames BIT STRING (SIZE(24)) + }, + subframeAllocation2 CHOICE { + oneFrame BIT STRING (SIZE(2)), + fourFrames BIT STRING (SIZE(8)) + } OPTIONAL, -- Need R + ... +} + +-- TAG-EUTRA-MBSFN-SUBFRAMECONFIGLIST-STOP +-- TAG-EUTRA-MULTIBANDINFOLIST-START + +EUTRA-MultiBandInfoList ::= SEQUENCE (SIZE (1..maxMultiBands)) OF EUTRA-MultiBandInfo + +EUTRA-MultiBandInfo ::= SEQUENCE { + eutra-FreqBandIndicator FreqBandIndicatorEUTRA, + eutra-NS-PmaxList EUTRA-NS-PmaxList OPTIONAL -- Need R +} + +-- TAG-EUTRA-MULTIBANDINFOLIST-STOP +-- TAG-EUTRA-NS-PMAXLIST-START + +EUTRA-NS-PmaxList ::= SEQUENCE (SIZE (1..maxEUTRA-NS-Pmax)) OF EUTRA-NS-PmaxValue + +EUTRA-NS-PmaxValue ::= SEQUENCE { + additionalPmax INTEGER (-30..33) OPTIONAL, -- Need R + additionalSpectrumEmission INTEGER (1..288) OPTIONAL -- Need R +} + +-- TAG-EUTRA-NS-PMAXLIST-STOP +-- TAG-EUTRA-PHYSCELLID-START + +EUTRA-PhysCellId ::= INTEGER (0..503) + +-- TAG-EUTRA-PHYSCELLID-STOP +-- TAG-EUTRA-PHYSCELLIDRANGE-START + +EUTRA-PhysCellIdRange ::= SEQUENCE { + start EUTRA-PhysCellId, + range ENUMERATED {n4, n8, n12, n16, n24, n32, n48, n64, n84, n96, + n128, n168, n252, n504, spare2, spare1} OPTIONAL -- Need N +} + +-- TAG-EUTRA-PHYSCELLIDRANGE-STOP +-- TAG-EUTRA-PRESENCEANTENNAPORT1-START + +EUTRA-PresenceAntennaPort1 ::= BOOLEAN + +-- TAG-EUTRA-PRESENCEANTENNAPORT1-STOP +-- TAG-EUTRA-Q-OFFSETRANGE-START + +EUTRA-Q-OffsetRange ::= ENUMERATED { + dB-24, dB-22, dB-20, dB-18, dB-16, dB-14, + dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3, + dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5, + dB6, dB8, dB10, dB12, dB14, dB16, dB18, + dB20, dB22, dB24} + +-- TAG-EUTRA-Q-OFFSETRANGE-STOP +-- TAG-IABIPADDRESS-START + +IAB-IP-Address-r16 ::= CHOICE { + iPv4-Address-r16 BIT STRING (SIZE(32)), + iPv6-Address-r16 BIT STRING (SIZE(128)), + iPv6-Prefix-r16 BIT STRING (SIZE(64)), + ... +} + +-- TAG-IABIPADDRESS-STOP +-- TAG-IABIPADDRESSINDEX-START + +IAB-IP-AddressIndex-r16 ::= INTEGER (1..maxIAB-IP-Address-r16) + +-- TAG-IABIPADDRESSINDEX-STOP +-- TAG-IAB-IP-USAGE-START + +IAB-IP-Usage-r16 ::= ENUMERATED {f1-c, f1-U, non-F1, spare} + +-- TAG-IAB-IP-USAGE-STOP +-- TAG-LOGGINGDURATION-START + +LoggingDuration-r16 ::= ENUMERATED { + min10, min20, min40, min60, min90, min120, spare2, spare1} + +-- TAG-LOGGINGDURATION-STOP +-- TAG-LOGGINGINTERVAL-START + +LoggingInterval-r16 ::= ENUMERATED { + ms320, ms640, ms1280, ms2560, ms5120, ms10240, ms20480, + ms30720, ms40960, ms61440 , infinity} + +-- TAG-LOGGINGINTERVAL-STOP +-- TAG-LOGMEASRESULTLISTBT-START + +LogMeasResultListBT-r16 ::= SEQUENCE (SIZE (1..maxBT-IdReport-r16)) OF LogMeasResultBT-r16 + +LogMeasResultBT-r16 ::= SEQUENCE { + bt-Addr-r16 BIT STRING (SIZE (48)), + rssi-BT-r16 INTEGER (-128..127) OPTIONAL, + ... +} + +-- TAG-LOGMEASRESULTLISTBT-STOP +-- TAG-LOGMEASRESULTLISTWLAN-START + +LogMeasResultListWLAN-r16 ::= SEQUENCE (SIZE (1..maxWLAN-Id-Report-r16)) OF LogMeasResultWLAN-r16 + +LogMeasResultWLAN-r16 ::= SEQUENCE { + wlan-Identifiers-r16 WLAN-Identifiers-r16, + rssiWLAN-r16 WLAN-RSSI-Range-r16 OPTIONAL, + rtt-WLAN-r16 WLAN-RTT-r16 OPTIONAL, + ... +} + +WLAN-Identifiers-r16 ::= SEQUENCE { + ssid-r16 OCTET STRING (SIZE (1..32)) OPTIONAL, + bssid-r16 OCTET STRING (SIZE (6)) OPTIONAL, + hessid-r16 OCTET STRING (SIZE (6)) OPTIONAL, + ... +} + +WLAN-RSSI-Range-r16 ::= INTEGER(0..141) + +WLAN-RTT-r16 ::= SEQUENCE { + rttValue-r16 INTEGER (0..16777215), + rttUnits-r16 ENUMERATED { + microseconds, + hundredsofnanoseconds, + tensofnanoseconds, + nanoseconds, + tenthsofnanoseconds, +... }, + rttAccuracy-r16 INTEGER (0..255) OPTIONAL, + ... +} + +-- TAG-OTHERCONFIG-START + +OtherConfig ::= SEQUENCE { + delayBudgetReportingConfig CHOICE{ + release NULL, + setup SEQUENCE{ + delayBudgetReportingProhibitTimer ENUMERATED {s0, s0dot4, s0dot8, s1dot6, s3, s6, s12, s30} + } + } OPTIONAL -- Need M +} + +OtherConfig-v1540 ::= SEQUENCE { + overheatingAssistanceConfig SetupRelease {OverheatingAssistanceConfig} OPTIONAL, -- Need M + ... +} +CandidateServingFreqListNR-r16 ::= SEQUENCE (SIZE (1..maxFreqIDC-r16)) OF ARFCN-ValueNR + +OtherConfig-v1610 ::= SEQUENCE { + idc-AssistanceConfig-r16 SetupRelease {IDC-AssistanceConfig-r16} OPTIONAL, -- Need M + drx-PreferenceConfig-r16 SetupRelease {DRX-PreferenceConfig-r16} OPTIONAL, -- Need M + maxBW-PreferenceConfig-r16 SetupRelease {MaxBW-PreferenceConfig-r16} OPTIONAL, -- Need M + maxCC-PreferenceConfig-r16 SetupRelease {MaxCC-PreferenceConfig-r16} OPTIONAL, -- Need M + maxMIMO-LayerPreferenceConfig-r16 SetupRelease {MaxMIMO-LayerPreferenceConfig-r16} OPTIONAL, -- Need M + minSchedulingOffsetPreferenceConfig-r16 SetupRelease {MinSchedulingOffsetPreferenceConfig-r16} OPTIONAL, -- Need M + releasePreferenceConfig-r16 SetupRelease {ReleasePreferenceConfig-r16} OPTIONAL, -- Need M + referenceTimePreferenceReporting-r16 ENUMERATED {true} OPTIONAL, -- Need R + btNameList-r16 SetupRelease {BT-NameList-r16} OPTIONAL, -- Need M + wlanNameList-r16 SetupRelease {WLAN-NameList-r16} OPTIONAL, -- Need M + sensorNameList-r16 SetupRelease {Sensor-NameList-r16} OPTIONAL, -- Need M + obtainCommonLocation-r16 ENUMERATED {true} OPTIONAL, -- Need R + sl-AssistanceConfigNR-r16 ENUMERATED{true} OPTIONAL -- Need R +} + +OverheatingAssistanceConfig ::= SEQUENCE { + overheatingIndicationProhibitTimer ENUMERATED {s0, s0dot5, s1, s2, s5, s10, s20, s30, + s60, s90, s120, s300, s600, spare3, spare2, spare1} +} + +IDC-AssistanceConfig-r16 ::= SEQUENCE { + candidateServingFreqListNR-r16 CandidateServingFreqListNR-r16 OPTIONAL, -- Need R + ... +} + +DRX-PreferenceConfig-r16 ::= SEQUENCE { + drx-PreferenceProhibitTimer-r16 ENUMERATED { + s0, s0dot5, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s20, s30, spare2, spare1} +} + +MaxBW-PreferenceConfig-r16 ::= SEQUENCE { + maxBW-PreferenceProhibitTimer-r16 ENUMERATED { + s0, s0dot5, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s20, s30, spare2, spare1} +} + +MaxCC-PreferenceConfig-r16 ::= SEQUENCE { + maxCC-PreferenceProhibitTimer-r16 ENUMERATED { + s0, s0dot5, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s20, s30, spare2, spare1} +} + +MaxMIMO-LayerPreferenceConfig-r16 ::= SEQUENCE { + maxMIMO-LayerPreferenceProhibitTimer-r16 ENUMERATED { + s0, s0dot5, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s20, s30, spare2, spare1} +} + +MinSchedulingOffsetPreferenceConfig-r16 ::= SEQUENCE { + minSchedulingOffsetPreferenceProhibitTimer-r16 ENUMERATED { + s0, s0dot5, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s20, s30, spare2, spare1} +} + +ReleasePreferenceConfig-r16 ::= SEQUENCE { + releasePreferenceProhibitTimer-r16 ENUMERATED { + s0, s0dot5, s1, s2, s3, s4, s5, s6, s7, + s8, s9, s10, s20, s30, infinity, spare1}, + connectedReporting ENUMERATED {true} OPTIONAL -- Need R +} + +-- TAG-OTHERCONFIG-STOP +-- TAG-PHYSCELLIDUTRA-FDD-START + +PhysCellIdUTRA-FDD-r16 ::= INTEGER (0..511) + +-- TAG-PHYSCELLIDUTRA-FDD-STOP +-- TAG-RRC-TRANSACTIONIDENTIFIER-START + +RRC-TransactionIdentifier ::= INTEGER (0..3) + +-- TAG-RRC-TRANSACTIONIDENTIFIER-STOP +-- TAG-SENSORNAMELIST-START + +Sensor-NameList-r16 ::= SEQUENCE { + measUncomBarPre-r16 ENUMERATED {true} OPTIONAL, -- Need R + measUeSpeed ENUMERATED {true} OPTIONAL, -- Need R + measUeOrientation ENUMERATED {true} OPTIONAL -- Need R +} + +-- TAG-SENSORNAMELIST-STOP +-- TAG-TRACEREFERENCE-START + +TraceReference-r16 ::= SEQUENCE { + plmn-Identity-r16 PLMN-Identity, + traceId-r16 OCTET STRING (SIZE (3)) +} + +-- TAG-TRACEREFERENCE-STOP +-- TAG-UEMeasurementsAvailable-START + +UEMeasurementsAvailable-r16 ::= SEQUENCE { + logMeasAvailable-r16 ENUMERATED {true} OPTIONAL, + logMeasAvailableBT-r16 ENUMERATED {true} OPTIONAL, + logMeasAvailableWLAN-r16 ENUMERATED {true} OPTIONAL, + connEstFailInfoAvailable-r16 ENUMERATED {true} OPTIONAL, + rlf-InfoAvailable-r16 ENUMERATED {true} OPTIONAL, + ... +} + +-- TAG-UEMeasurementsAvailable-STOP +-- TAG-UTRA-FDD-Q-OFFSETRANGE-START + +UTRA-FDD-Q-OffsetRange-r16 ::= ENUMERATED { + dB-24, dB-22, dB-20, dB-18, dB-16, dB-14, + dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3, + dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5, + dB6, dB8, dB10, dB12, dB14, dB16, dB18, + dB20, dB22, dB24} + +-- TAG-UTRA-FDD-Q-OFFSETRANGE-STOP +-- TAG-VISITEDCELLINFOLIST-START + +VisitedCellInfoList-r16 ::= SEQUENCE (SIZE (1..maxCellHistory-r16)) OF VisitedCellInfo-r16 + +VisitedCellInfo-r16 ::= SEQUENCE { + visitedCellId-r16 CHOICE { + nr-CellId-r16 CHOICE { + cgi-Info CGI-Info-Logging-r16, + pci-arfcn-r16 SEQUENCE { + physCellId-r16 PhysCellId, + carrierFreq-r16 ARFCN-ValueNR + } + }, + eutra-CellId-r16 CHOICE { + cellGlobalId-r16 CGI-InfoEUTRA, + pci-arfcn-r16 SEQUENCE { + physCellId-r16 EUTRA-PhysCellId, + carrierFreq-r16 ARFCN-ValueEUTRA + } + } + } OPTIONAL, + timeSpent-r16 INTEGER (0..4095), + ... +} + +-- TAG-VISITEDCELLINFOLIST-STOP +-- TAG-WLANNAMELIST-START + +WLAN-NameList-r16 ::= SEQUENCE (SIZE (1..maxWLAN-Name-r16)) OF WLAN-Name-r16 + +WLAN-Name-r16 ::= OCTET STRING (SIZE (1..32)) + +-- TAG-SL-BWP-CONFIG-START + +SL-BWP-Config-r16 ::= SEQUENCE { + sl-BWP-Id BWP-Id, + sl-BWP-Generic-r16 SL-BWP-Generic-r16 OPTIONAL, -- Need M + sl-BWP-PoolConfig-r16 SL-BWP-PoolConfig-r16 OPTIONAL, -- Need M + ... +} + +SL-BWP-Generic-r16 ::= SEQUENCE { + sl-BWP-r16 BWP OPTIONAL, -- Need M + sl-LengthSymbols-r16 ENUMERATED {sym7, sym8, sym9, sym10, sym11, sym12, sym13, sym14} OPTIONAL, -- Need M + sl-StartSymbol-r16 ENUMERATED {sym0, sym1, sym2, sym3, sym4, sym5, sym6, sym7} OPTIONAL, -- Need M + sl-PSBCH-Config-r16 SetupRelease {SL-PSBCH-Config-r16} OPTIONAL, -- Need M + sl-TxDirectCurrentLocation-r16 INTEGER (0..3301) OPTIONAL, -- Need M + ... +} + +-- TAG-SL-BWP-CONFIG-STOP +-- TAG-SL-BWP-CONFIGCOMMON-START + +SL-BWP-ConfigCommon-r16 ::= SEQUENCE { + sl-BWP-Generic-r16 SL-BWP-Generic-r16 OPTIONAL, -- Need R + sl-BWP-PoolConfigCommon-r16 SL-BWP-PoolConfigCommon-r16 OPTIONAL, -- Need R + ... +} + +-- TAG-SL-BWP-CONFIGCOMMON-STOP +-- TAG-SL-BWP-POOLCONFIG-START + +SL-BWP-PoolConfig-r16 ::= SEQUENCE { + sl-RxPool-r16 SEQUENCE (SIZE (1..maxNrofRXPool-r16)) OF SL-ResourcePool-r16 OPTIONAL, -- Cond HO + sl-TxPoolSelectedNormal-r16 SL-TxPoolDedicated-r16 OPTIONAL, -- Need M + sl-TxPoolScheduling-r16 SL-TxPoolDedicated-r16 OPTIONAL, -- Need N + sl-TxPoolExceptional-r16 SL-ResourcePoolConfig-r16 OPTIONAL -- Need M +} + +SL-TxPoolDedicated-r16 ::= SEQUENCE { + sl-PoolToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofTXPool-r16)) OF SL-ResourcePoolID-r16 OPTIONAL, -- Need N + sl-PoolToAddModList-r16 SEQUENCE (SIZE (1..maxNrofTXPool-r16)) OF SL-ResourcePoolConfig-r16 OPTIONAL -- Need N +} + +SL-ResourcePoolConfig-r16 ::= SEQUENCE { + sl-ResourcePoolID-r16 SL-ResourcePoolID-r16, + sl-ResourcePool-r16 SL-ResourcePool-r16 OPTIONAL -- Need M +} + +SL-ResourcePoolID-r16 ::= INTEGER (1..maxNrofPoolID-r16) + +-- TAG-SL-BWP-POOLCONFIG-STOP +-- TAG-SL-BWP-POOLCONFIGCOMMON-START + +SL-BWP-PoolConfigCommon-r16 ::= SEQUENCE { + sl-RxPool-r16 SEQUENCE (SIZE (1..maxNrofRXPool-r16)) OF SL-ResourcePool-r16 OPTIONAL, -- Need R + sl-TxPoolSelectedNormal-r16 SEQUENCE (SIZE (1..maxNrofTXPool-r16)) OF SL-ResourcePoolConfig-r16 OPTIONAL, -- Need R + sl-TxPoolExceptional-r16 SL-ResourcePoolConfig-r16 OPTIONAL -- Need R +} + +-- TAG-SL-BWP-POOLCONFIGCOMMON-STOP +-- TAG-SL-CBR-PRIORITYTXCONFIGLIST-START + +SL-CBR-PriorityTxConfigList-r16 ::= SEQUENCE (SIZE (1..8)) OF SL-PriorityTxConfigIndex-r16 + +SL-PriorityTxConfigIndex-r16 ::= SEQUENCE { + sl-PriorityThreshold-r16 INTEGER (1..8) OPTIONAL, -- Need M + sl-DefaultTxConfigIndex-r16 INTEGER (0..maxCBR-Level-1-r16) OPTIONAL, -- Need M + sl-CBR-ConfigIndex-r16 INTEGER (0..maxCBR-Config-1-r16) OPTIONAL, -- Need M + sl-Tx-ConfigIndexList-r16 SEQUENCE (SIZE (1.. maxCBR-Level-r16)) OF SL-TxConfigIndex-r16 OPTIONAL -- Need M +} + +SL-TxConfigIndex-r16 ::= INTEGER (0..maxTxConfig-1-r16) + +-- TAG-SL-CBR-PRIORITYTXCONFIGLIST-STOP +-- TAG-SL-CBR-COMMONTXCONFIGLIST-START + +SL-CBR-CommonTxConfigList-r16 ::= SEQUENCE { + sl-CBR-RangeConfigList-r16 SEQUENCE (SIZE (1..maxCBR-Config-r16)) OF SL-CBR-LevelsConfig-r16 OPTIONAL, -- Need M + sl-CBR-PSSCH-TxConfigList-r16 SEQUENCE (SIZE (1.. maxTxConfig-r16)) OF SL-CBR-PSSCH-TxConfig-r16 OPTIONAL -- Need M +} + +SL-CBR-LevelsConfig-r16 ::= SEQUENCE (SIZE (1..maxCBR-Level-r16)) OF SL-CBR-r16 + +SL-CBR-PSSCH-TxConfig-r16 ::= SEQUENCE { + sl-CR-Limit-r16 INTEGER(0..10000) OPTIONAL, -- Need M + sl-TxParameters-r16 SL-PSSCH-TxParameters-r16 OPTIONAL -- Need M +} + +SL-CBR-r16 ::= INTEGER (0..100) + +-- TAG-SL-CBR-COMMONTXCONFIGLIST-STOP +-- TAG-SL-CONFIGDEDICATEDNR-START + +SL-ConfigDedicatedNR-r16 ::= SEQUENCE { + sl-PHY-MAC-RLC-Config-r16 SL-PHY-MAC-RLC-Config-r16 OPTIONAL, -- Need M + sl-RadioBearerToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofSLRB-r16)) OF SLRB-Uu-ConfigIndex-r16 OPTIONAL, -- Need N + sl-RadioBearerToAddModList-r16 SEQUENCE (SIZE (1..maxNrofSLRB-r16)) OF SL-RadioBearerConfig-r16 OPTIONAL, -- Need N + sl-MeasConfigInfoToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofSL-Dest-r16)) OF SL-DestinationIndex-r16 OPTIONAL, -- Need N + sl-MeasConfigInfoToAddModList-r16 SEQUENCE (SIZE (1..maxNrofSL-Dest-r16)) OF SL-MeasConfigInfo-r16 OPTIONAL, -- Need M + t400-r16 ENUMERATED {ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, ms2000} OPTIONAL, -- Need M + ... +} + +SL-DestinationIndex-r16 ::= INTEGER (0..maxNrofSL-Dest-1-r16) + +SL-PHY-MAC-RLC-Config-r16::= SEQUENCE { + sl-ScheduledConfig-r16 SetupRelease { SL-ScheduledConfig-r16 } OPTIONAL, -- Need M + sl-UE-SelectedConfig-r16 SetupRelease { SL-UE-SelectedConfig-r16 } OPTIONAL, -- Need M + sl-FreqInfoToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF SL-Freq-Id-r16 OPTIONAL, -- Need N + sl-FreqInfoToAddModList-r16 SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF SL-FreqConfig-r16 OPTIONAL, -- Need N + sl-RLC-BearerToReleaseList-r16 SEQUENCE (SIZE (1..maxSL-LCID-r16)) OF SL-RLC-BearerConfigIndex-r16 OPTIONAL, -- Need N + sl-RLC-BearerToAddModList-r16 SEQUENCE (SIZE (1..maxSL-LCID-r16)) OF SL-RLC-BearerConfig-r16 OPTIONAL, -- Need N + sl-MaxNumConsecutiveDTX-r16 ENUMERATED {n1, n2, n3, n4, n6, n8, n16, n32} OPTIONAL, -- Need M + sl-CSI-Acquisition-r16 ENUMERATED {enabled} OPTIONAL, -- Need R + sl-CSI-SchedulingRequestId-r16 SetupRelease {SchedulingRequestId} OPTIONAL, -- Need M + sl-SSB-PriorityNR-r16 INTEGER (1..8) OPTIONAL, -- Need R + networkControlledSyncTx-r16 ENUMERATED {on, off} OPTIONAL -- Need M +} + +-- TAG-SL-CONFIGDEDICATEDNR-STOP +-- TAG-SL-CONFIGUREDGRANTCONFIG-START + +SL-ConfiguredGrantConfig-r16 ::= SEQUENCE { + sl-ConfigIndexCG-r16 SL-ConfigIndexCG-r16, + sl-PeriodCG-r16 SL-PeriodCG-r16 OPTIONAL, -- Need M + sl-NrOfHARQ-Processes-r16 INTEGER (1..16) OPTIONAL, -- Need M + sl-HARQ-ProcID-offset-r16 INTEGER (1..16) OPTIONAL, -- Need M + sl-CG-MaxTransNumList-r16 SL-CG-MaxTransNumList-r16 OPTIONAL, -- Need M + rrc-ConfiguredSidelinkGrant SEQUENCE { + sl-TimeResourceCG-Type1-r16 INTEGER (0..496) OPTIONAL, -- Need M + sl-StartSubchannelCG-Type1-r16 INTEGER (0..26) OPTIONAL, -- Need M + sl-FreqResourceCG-Type1-r16 INTEGER (0..6929) OPTIONAL, -- Need M + sl-TimeOffsetCG-Type1-r16 INTEGER (0..7999) OPTIONAL, -- Need R + sl-N1PUCCH-AN-r16 PUCCH-ResourceId OPTIONAL, -- Need M + sl-PSFCH-ToPUCCH-CG-Type1-r16 INTEGER (0..15) OPTIONAL -- Need M + } OPTIONAL, -- Need M + ... +} + +SL-ConfigIndexCG-r16 ::= INTEGER (1..maxNrofCG-SL-r16) + +SL-CG-MaxTransNumList-r16 ::= SEQUENCE (SIZE (1..8)) OF SL-CG-MaxTransNum-r16 + +SL-CG-MaxTransNum-r16 ::= SEQUENCE { + sl-Priority-r16 INTEGER (1..8), + sl-MaxTransNum-r16 INTEGER (1..32) +} + +SL-PeriodCG-r16 ::= CHOICE{ + sl-PeriodCG1-r16 ENUMERATED {ms0, ms100, ms200, ms300, ms400, ms500, ms600, ms700, ms800, ms900, ms1000}, + sl-PeriodCG2-r16 INTEGER (1..99) +} + +-- TAG-SL-CONFIGUREDGRANTCONFIG-STOP +-- TAG-SL-DESTINATIONIDENTITY-START + +SL-DestinationIdentity-r16 ::= BIT STRING (SIZE (24)) + +-- TAG-SL-DESTINATIONIDENTITY-STOP +-- TAG-SL-FREQCONFIG-START + +SL-FreqConfig-r16 ::= SEQUENCE { + sl-Freq-Id-r16 SL-Freq-Id-r16, + sl-SCS-SpecificCarrierList-r16 SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier, + sl-AbsoluteFrequencyPointA-r16 ARFCN-ValueNR OPTIONAL, -- Need M + sl-AbsoluteFrequencySSB-r16 ARFCN-ValueNR OPTIONAL, -- Need R + frequencyShift7p5khzSL-r16 ENUMERATED {true} OPTIONAL, -- Cond V2X-SL-Shared + valueN-r16 INTEGER (-1..1), + sl-BWP-ToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofSL-BWPs-r16)) OF BWP-Id OPTIONAL, -- Need N + sl-BWP-ToAddModList-r16 SEQUENCE (SIZE (1..maxNrofSL-BWPs-r16)) OF SL-BWP-Config-r16 OPTIONAL, -- Need N + sl-SyncConfigList-r16 SL-SyncConfigList-r16 OPTIONAL, -- Need M + sl-SyncPriority-r16 ENUMERATED {gnss, gnbEnb} OPTIONAL -- Need M +} + +SL-Freq-Id-r16 ::= INTEGER (1.. maxNrofFreqSL-r16) + +-- TAG-SL-FREQCONFIG-STOP +-- TAG-SL-FREQCONFIGCOMMON-START + +SL-FreqConfigCommon-r16 ::= SEQUENCE { + sl-SCS-SpecificCarrierList-r16 SEQUENCE (SIZE (1..maxSCSs)) OF SCS-SpecificCarrier, + sl-AbsoluteFrequencyPointA-r16 ARFCN-ValueNR, + sl-AbsoluteFrequencySSB-r16 ARFCN-ValueNR OPTIONAL, -- Need R + frequencyShift7p5khzSL-r16 ENUMERATED {true} OPTIONAL, -- Cond V2X-SL-Shared + valueN-r16 INTEGER (-1..1), + sl-BWP-List-r16 SEQUENCE (SIZE (1..maxNrofSL-BWPs-r16)) OF SL-BWP-ConfigCommon-r16 OPTIONAL, -- Need R + sl-SyncPriority-r16 ENUMERATED {gnss, gnbEnb} OPTIONAL, -- Need R + sl-NbAsSync-r16 BOOLEAN OPTIONAL, -- Need R + sl-SyncConfigList-r16 SL-SyncConfigList-r16 OPTIONAL, -- Need R + ... +} +-- TAG-SL-FREQCONFIGCOMMON-STOP +-- TAG-SL-LOGICALCHANNELCONFIG-START + +SL-LogicalChannelConfig-r16 ::= SEQUENCE { + sl-Priority-r16 INTEGER (1..8), + sl-PrioritisedBitRate-r16 ENUMERATED {kBps0, kBps8, kBps16, kBps32, kBps64, kBps128, kBps256, kBps512, + kBps1024, kBps2048, kBps4096, kBps8192, kBps16384, kBps32768, kBps65536, infinity}, + sl-BucketSizeDuration-r16 ENUMERATED {ms5, ms10, ms20, ms50, ms100, ms150, ms300, ms500, ms1000, + spare7, spare6, spare5, spare4, spare3,spare2, spare1}, + sl-ConfiguredGrantType1Allowed-r16 ENUMERATED {true} OPTIONAL, -- Need R + sl-HARQ-FeedbackEnabled-r16 ENUMERATED {enabled, disabled } OPTIONAL, -- Need R + sl-AllowedCG-List-r16 SEQUENCE (SIZE (0.. maxNrofCG-SL-r16-1)) OF SL-ConfigIndexCG-r16 + OPTIONAL, -- Need R + sl-AllowedSCS-List-r16 SEQUENCE (SIZE (1..maxSCSs)) OF SubcarrierSpacing OPTIONAL, -- Need R + sl-MaxPUSCH-Duration-r16 ENUMERATED {ms0p02, ms0p04, ms0p0625, ms0p125, ms0p25, ms0p5, spare2, spare1} + OPTIONAL, -- Need R + sl-LogicalChannelGroup-r16 INTEGER (0..maxLCG-ID) OPTIONAL, -- Need R + sl-SchedulingRequestId-r16 SchedulingRequestId OPTIONAL, -- Need R + sl-LogicalChannelSR-DelayTimerApplied-r16 BOOLEAN OPTIONAL, -- Need R + ... +} +-- TAG-SL-LOGICALCHANNELCONFIG-STOP +-- TAG-SL-MEASCONFIGCOMMON-START + +SL-MeasConfigCommon-r16 ::= SEQUENCE { + sl-MeasObjectListCommon-r16 SL-MeasObjectList-r16 OPTIONAL, -- Need R + sl-ReportConfigListCommon-r16 SL-ReportConfigList-r16 OPTIONAL, -- Need R + sl-MeasIdListCommon-r16 SL-MeasIdList-r16 OPTIONAL, -- Need R + sl-QuantityConfigCommon-r16 SL-QuantityConfig-r16 OPTIONAL, -- Need R + ... +} + +-- TAG-SL-MEASCONFIGCOMMON-STOP +-- TAG-SL-MEASCONFIGINFO-START + +SL-MeasConfigInfo-r16 ::= SEQUENCE { + sl-DestinationIndex-r16 SL-DestinationIndex-r16, + sl-MeasConfig-r16 SL-MeasConfig-r16, + ... +} + +SL-MeasConfig-r16 ::= SEQUENCE { + sl-MeasObjectToRemoveList-r16 SL-MeasObjectToRemoveList-r16 OPTIONAL, -- Need N + sl-MeasObjectToAddModList-r16 SL-MeasObjectList-r16 OPTIONAL, -- Need N + sl-ReportConfigToRemoveList-r16 SL-ReportConfigToRemoveList-r16 OPTIONAL, -- Need N + sl-ReportConfigToAddModList-r16 SL-ReportConfigList-r16 OPTIONAL, -- Need N + sl-MeasIdToRemoveList-r16 SL-MeasIdToRemoveList-r16 OPTIONAL, -- Need N + sl-MeasIdToAddModList-r16 SL-MeasIdList-r16 OPTIONAL, -- Need N + sl-QuantityConfig-r16 SL-QuantityConfig-r16 OPTIONAL, -- Need M + ... +} + +SL-MeasObjectToRemoveList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-ObjectId-r16)) OF SL-MeasObjectId-r16 + +SL-ReportConfigToRemoveList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-ReportConfigId-r16)) OF SL-ReportConfigId-r16 + +SL-MeasIdToRemoveList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-MeasId-r16)) OF SL-MeasId-r16 + +-- TAG-SL-MEASCONFIGINFO-STOP +-- TAG-SL-MEASIDLIST-START + +SL-MeasIdList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-MeasId-r16)) OF SL-MeasIdInfo-r16 + +SL-MeasIdInfo-r16 ::= SEQUENCE { + sl-MeasId-r16 SL-MeasId-r16, + sl-MeasObjectId-r16 SL-MeasObjectId-r16, + sl-ReportConfigId-r16 SL-ReportConfigId-r16, + ... +} + +SL-MeasId-r16 ::= INTEGER (1..maxNrofSL-MeasId-r16) + +-- TAG-SL-MEASIDLIST-STOP +-- TAG-SL-MEASOBJECTLIST-START + +SL-MeasObjectList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-ObjectId-r16)) OF SL-MeasObjectInfo-r16 + +SL-MeasObjectInfo-r16 ::= SEQUENCE { + sl-MeasObjectId-r16 SL-MeasObjectId-r16, + sl-MeasObject-r16 SL-MeasObject-r16, + ... +} + +SL-MeasObjectId-r16 ::= INTEGER (1..maxNrofSL-ObjectId-r16) + +SL-MeasObject-r16 ::= SEQUENCE { + frequencyInfoSL-r16 ARFCN-ValueNR, + ... +} + +-- TAG-SL-MEASOBJECTLIST-STOP +-- TAG-SL-PDCP-CONFIG-START + +SL-PDCP-Config-r16 ::= SEQUENCE { + sl-DiscardTimer-r16 ENUMERATED {ms3, ms10, ms20, ms25, ms30, ms40, ms50, ms60, ms75, ms100, ms150, ms200, + ms250, ms300, ms500, ms750, ms1500, infinity} OPTIONAL, -- Cond Setup + sl-PDCP-SN-Size-r16 ENUMERATED {len12bits, len18bits} OPTIONAL, -- Cond Setup2 + sl-OutOfOrderDelivery ENUMERATED { true } OPTIONAL, -- Need R + ... +} + +-- TAG-SL-PDCP-CONFIG-STOP +-- TAG-SL-PSBCH-CONFIG-START + +SL-PSBCH-Config-r16 ::= SEQUENCE { + dl-P0-PSBCH-r16 INTEGER (-16..15) OPTIONAL, -- Need M + dl-Alpha-PSBCH-r16 ENUMERATED {alpha0, alpha04, alpha05, alpha06, alpha07, alpha08, alpha09, alpha1} OPTIONAL, -- Need M + ... +} + +-- TAG-SL-PSBCH-CONFIG-STOP +-- TAG-SL-PSSCH-TXCONFIGLIST-START + +SL-PSSCH-TxConfigList-r16 ::= SEQUENCE (SIZE (1..maxPSSCH-TxConfig-r16)) OF SL-PSSCH-TxConfig-r16 + +SL-PSSCH-TxConfig-r16 ::= SEQUENCE { + sl-TypeTxSync-r16 SL-TypeTxSync-r16 OPTIONAL, -- Need R + sl-ThresUE-Speed-r16 ENUMERATED {kmph60, kmph80, kmph100, kmph120, + kmph140, kmph160, kmph180, kmph200}, + sl-ParametersAboveThres-r16 SL-PSSCH-TxParameters-r16, + sl-ParametersBelowThres-r16 SL-PSSCH-TxParameters-r16, + ... +} + + +SL-PSSCH-TxParameters-r16 ::= SEQUENCE { + sl-MinMCS-PSSCH-r16 INTEGER (0..27), + sl-MaxMCS-PSSCH-r16 INTEGER (0..31), + sl-MinSubChannelNumPSSCH-r16 INTEGER (1..27), + sl-MaxSubchannelNumPSSCH-r16 INTEGER (1..27), + sl-MaxTxTransNumPSSCH-r16 INTEGER (1..32), + sl-MaxTxPower-r16 SL-TxPower-r16 OPTIONAL -- Cond CBR +} + +-- TAG-SL-PSSCH-TXCONFIGLIST-STOP +-- TAG-SL-QOS-FLOWIDENTITY-START + +SL-QoS-FlowIdentity-r16 ::= INTEGER (1..maxNrofSL-QFIs-r16) + +-- TAG-SL-QOS-FLOWIDENTITY-STOP +-- TAG-SL-QOS-PROFILE-START + +SL-QoS-Profile-r16 ::= SEQUENCE { + sl-PQI-r16 SL-PQI-r16 OPTIONAL, -- Need R + sl-GFBR-r16 INTEGER (0..4000000000) OPTIONAL, -- Need R + sl-MFBR-r16 INTEGER (0..4000000000) OPTIONAL, -- Need R + sl-Range-r16 INTEGER (1..1000) OPTIONAL, -- Need R + ... +} + +SL-PQI-r16 ::= CHOICE { + sl-StandardizedPQI-r16 INTEGER (0..255), + sl-Non-StandardizedPQI-r16 SEQUENCE { + sl-ResourceType-r16 ENUMERATED {gbr, non-GBR, delayCriticalGBR, spare1} OPTIONAL, -- Need R + sl-PriorityLevel-r16 INTEGER (1..8) OPTIONAL, -- Need R + sl-PacketDelayBudget-r16 INTEGER (0..1023) OPTIONAL, -- Need R + sl-PacketErrorRate-r16 INTEGER (0..9) OPTIONAL, -- Need R + sl-AveragingWindow-r16 INTEGER (0..4095) OPTIONAL, -- Need R + sl-MaxDataBurstVolume-r16 INTEGER (0..4095) OPTIONAL, -- Need R + ... + } +} + +-- TAG-SL-QOS-PROFILE-STOP +-- TAG-SL-QUANTITYCONFIG-START + +SL-QuantityConfig-r16 ::= SEQUENCE { + sl-FilterCoefficientDMRS-r16 FilterCoefficient DEFAULT fc4, + ... +} + +-- TAG-SL-QuantityConfig-STOP +-- TAG-SL-RADIOBEARERCONFIG-START + +SL-RadioBearerConfig-r16 ::= SEQUENCE { + slrb-Uu-ConfigIndex-r16 SLRB-Uu-ConfigIndex-r16, + sl-SDAP-Config-r16 SL-SDAP-Config-r16 OPTIONAL, -- Cond SLRBSetup + sl-PDCP-Config-r16 SL-PDCP-Config-r16 OPTIONAL, -- Cond SLRBSetup + sl-TransRange-r16 ENUMERATED {m20, m50, m80, m100, m120, m150, m180, m200, m220, m250, m270, m300, m350, m370, + m400, m420, m450, m480, m500, m550, m600, m700, m1000, spare9, spare8, spare7, spare6, + spare5, spare4, spare3, spare2, spare1} OPTIONAL, -- Need R + ... +} + +-- TAG-SL-RADIOBEARERCONFIG-STOP +-- TAG-SL-REPORTCONFIGLIST-START + +SL-ReportConfigList-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-ReportConfigId-r16)) OF SL-ReportConfigInfo-r16 + +SL-ReportConfigInfo-r16 ::= SEQUENCE { + sl-ReportConfigId-r16 SL-ReportConfigId-r16, + sl-ReportConfig-r16 SL-ReportConfig-r16, + ... +} + +SL-ReportConfigId-r16 ::= INTEGER (1..maxNrofSL-ReportConfigId-r16) + +SL-ReportConfig-r16 ::= SEQUENCE { + sl-ReportType-r16 CHOICE { + sl-Periodical-r16 SL-PeriodicalReportConfig-r16, + sl-EventTriggered-r16 SL-EventTriggerConfig-r16, + ... + }, + ... +} + +SL-PeriodicalReportConfig-r16 ::= SEQUENCE { + sl-ReportInterval-r16 ReportInterval, + sl-ReportAmount-r16 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + sl-ReportQuantity-r16 SL-MeasReportQuantity-r16, + sl-RS-Type-r16 SL-RS-Type-r16, + ... +} + +SL-EventTriggerConfig-r16 ::= SEQUENCE { + sl-EventId-r16 CHOICE { + eventS1-r16 SEQUENCE { + s1-Threshold-r16 SL-MeasTriggerQuantity-r16, + sl-ReportOnLeave-r16 BOOLEAN, + sl-Hysteresis-r16 Hysteresis, + sl-TimeToTrigger-r16 TimeToTrigger, + ... + }, + eventS2-r16 SEQUENCE { + s2-Threshold-r16 SL-MeasTriggerQuantity-r16, + sl-ReportOnLeave-r16 BOOLEAN, + sl-Hysteresis-r16 Hysteresis, + sl-TimeToTrigger-r16 TimeToTrigger, + ... + }, + ... + }, + sl-ReportInterval-r16 ReportInterval, + sl-ReportAmount-r16 ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, + sl-ReportQuantity-r16 SL-MeasReportQuantity-r16, + sl-RS-Type-r16 SL-RS-Type-r16, + ... +} + +SL-MeasReportQuantity-r16 ::= CHOICE { + sl-RSRP-r16 RSRP-Range, + ... +} + +SL-MeasTriggerQuantity-r16 ::= CHOICE { + sl-RSRP-r16 RSRP-Range, + ... +} + +SL-RS-Type-r16 ::= ENUMERATED {dmrs, spare3, spare2, spare1} + +-- TAG-SL-REPORTCONFIGLIST-STOP +-- TAG-SL-RESOURCEPOOL-START + +SL-ResourcePool-r16 ::= SEQUENCE { + sl-PSCCH-Config-r16 SetupRelease { SL-PSCCH-Config-r16 } OPTIONAL, -- Need M + sl-PSSCH-Config-r16 SetupRelease { SL-PSSCH-Config-r16 } OPTIONAL, -- Need M + sl-PSFCH-Config-r16 SetupRelease { SL-PSFCH-Config-r16 } OPTIONAL, -- Need M + sl-SyncAllowed-r16 SL-SyncAllowed-r16 OPTIONAL, -- Need M + sl-SubchannelSize-r16 ENUMERATED {n10, n12, n15, n20, n25, n50, n75, n100} OPTIONAL, -- Need M + sl-TimeResource-r16 INTEGER (10..160) OPTIONAL, -- Need M + sl-StartRB-Subchannel-r16 INTEGER (0..265) OPTIONAL, -- Need M + sl-NumSubchannel-r16 INTEGER (1..27) OPTIONAL, -- Need M + sl-Additional-MCS-Table-r16 ENUMERATED {qam256, qam64LowSE, qam256-qam64LowSE } OPTIONAL, -- Need M + sl-ThreshS-RSSI-CBR-r16 INTEGER (0..45) OPTIONAL, -- Need M + sl-TimeWindowSizeCBR-r16 ENUMERATED {ms100, slot100} OPTIONAL, -- Need M + sl-TimeWindowSizeCR-r16 ENUMERATED {ms1000, slot1000} OPTIONAL, -- Need M + sl-PTRS-Config-r16 SL-PTRS-Config-r16 OPTIONAL, -- Need M + sl-UE-SelectedConfigRP-r16 SL-UE-SelectedConfigRP-r16 OPTIONAL, -- Need M + sl-RxParametersNcell-r16 SEQUENCE { + sl-TDD-Configuration-r16 TDD-UL-DL-ConfigCommon OPTIONAL, -- Need M + sl-SyncConfigIndex-r16 INTEGER (0..15) + } OPTIONAL, -- Need M + sl-ZoneConfigMCR-List-r16 SEQUENCE (SIZE (16)) OF SL-ZoneConfigMCR-r16 OPTIONAL, -- Need M + sl-FilterCoefficient-r16 FilterCoefficient OPTIONAL, -- Need M + sl-RB-Number-r16 INTEGER (10..275) OPTIONAL, -- Need M + sl-PreemptionEnable-r16 ENUMERATED {enabled, pl1, pl2, pl3, pl4, pl5, pl6, pl7, pl8} OPTIONAL, -- Need R + sl-PriorityThreshold-UL-URLLC-r16 INTEGER (1..9) OPTIONAL, -- Need M + sl-PriorityThreshold-r16 INTEGER (1..9) OPTIONAL, -- Need M + sl-X-Overhead-r16 ENUMERATED {n0,n3, n6, n9} OPTIONAL, -- Need M + sl-PowerControl-r16 SL-PowerControl-r16 OPTIONAL, -- Need M + sl-TxPercentageList-r16 SL-TxPercentageList-r16 OPTIONAL, -- Need M + sl-MinMaxMCS-List-r16 SL-MinMaxMCS-List-r16 OPTIONAL, -- Need M +... +} + +SL-ZoneConfigMCR-r16 ::= SEQUENCE { + sl-ZoneConfigMCR-Index-r16 INTEGER (0..15), + sl-TransRange-r16 ENUMERATED {m20, m50, m80, m100, m120, m150, m180, m200, m220, m250, m270, m300, m350, + m370, m400, m420, m450, m480, m500, m550, m600, m700, m1000, spare8, spare7, + spare6, spare5, spare4, spare3, spare2, spare1} OPTIONAL, -- Need M + sl-ZoneConfig-r16 SL-ZoneConfig-r16 OPTIONAL, -- Need M +... +} + +SL-SyncAllowed-r16 ::= SEQUENCE { + gnss-Sync-r16 ENUMERATED {true} OPTIONAL, -- Need R + gnbEnb-Sync-r16 ENUMERATED {true} OPTIONAL, -- Need R + ue-Sync-r16 ENUMERATED {true} OPTIONAL -- Need R +} + +SL-PSCCH-Config-r16 ::= SEQUENCE { + sl-TimeResourcePSCCH-r16 ENUMERATED {n2, n3} OPTIONAL, -- Need M + sl-FreqResourcePSCCH-r16 ENUMERATED {n10,n12, n15, n20, n25} OPTIONAL, -- Need M + sl-DMRS-ScrambleID-r16 INTEGER (0..65535) OPTIONAL, -- Need M + sl-NumReservedBits-r16 INTEGER (2..4) OPTIONAL, -- Need M + ... +} + +SL-PSSCH-Config-r16 ::= SEQUENCE { + sl-PSSCH-DMRS-TimePatternList-r16 SEQUENCE (SIZE (1..3)) OF INTEGER (2..4) OPTIONAL, -- Need M + sl-BetaOffsets2ndSCI-r16 SEQUENCE (SIZE (4)) OF SL-BetaOffsets-r16 OPTIONAL, -- Need M + sl-Scaling-r16 ENUMERATED {f0p5, f0p65, f0p8, f1} OPTIONAL, -- Need M + ... +} + +SL-PSFCH-Config-r16 ::= SEQUENCE { + sl-PSFCH-Period-r16 ENUMERATED {sl0, sl1, sl2, sl4} OPTIONAL, -- Need M + sl-PSFCH-RB-Set-r16 BIT STRING (SIZE (10..275)) OPTIONAL, -- Need M + sl-NumMuxCS-Pair-r16 ENUMERATED {n1, n2, n3, n6} OPTIONAL, -- Need M + sl-MinTimeGapPSFCH-r16 ENUMERATED {sl2, sl3} OPTIONAL, -- Need M + sl-PSFCH-HopID-r16 INTEGER (0..1023) OPTIONAL, -- Need M + sl-PSFCH-CandidateResourceType-r16 ENUMERATED {startSubCH, allocSubCH} OPTIONAL, -- Need M + ... +} +SL-PTRS-Config-r16 ::= SEQUENCE { + sl-PTRS-FreqDensity-r16 SEQUENCE (SIZE (2)) OF INTEGER (1..276) OPTIONAL, -- Need M + sl-PTRS-TimeDensity-r16 SEQUENCE (SIZE (3)) OF INTEGER (0..29) OPTIONAL, -- Need M + sl-PTRS-RE-Offset-r16 ENUMERATED {offset01, offset10, offset11} OPTIONAL, -- Need M + ... +} + +SL-UE-SelectedConfigRP-r16 ::= SEQUENCE { + sl-CBR-PriorityTxConfigList-r16 SL-CBR-PriorityTxConfigList-r16 OPTIONAL, -- Need M + sl-ThresPSSCH-RSRP-List-r16 SL-ThresPSSCH-RSRP-List-r16 OPTIONAL, -- Need M + sl-MultiReserveResource-r16 ENUMERATED {enabled} OPTIONAL, -- Need M + sl-MaxNumPerReserve-r16 ENUMERATED {n2, n3} OPTIONAL, -- Need M + sl-SensingWindow-r16 ENUMERATED {ms100, ms1100} OPTIONAL, -- Need M + sl-SelectionWindowList-r16 SL-SelectionWindowList-r16 OPTIONAL, -- Need M + sl-ResourceReservePeriodList-r16 SEQUENCE (SIZE (1..16)) OF SL-ResourceReservePeriod-r16 OPTIONAL, -- Need M + sl-RS-ForSensing-r16 ENUMERATED {pscch, pssch}, + ... +} + +SL-ResourceReservePeriod-r16 ::= CHOICE { + sl-ResourceReservePeriod1-r16 ENUMERATED {ms0, ms100, ms200, ms300, ms400, ms500, ms600, ms700, ms800, ms900, ms1000}, + sl-ResourceReservePeriod2-r16 INTEGER (1..99) +} + +SL-SelectionWindowList-r16 ::= SEQUENCE (SIZE (8)) OF SL-SelectionWindowConfig-r16 + +SL-SelectionWindowConfig-r16 ::= SEQUENCE { + sl-Priority-r16 INTEGER (1..8), + sl-SelectionWindow-r16 ENUMERATED {n1, n5, n10, n20} +} + +SL-TxPercentageList-r16 ::= SEQUENCE (SIZE (8)) OF SL-TxPercentageConfig-r16 + +SL-TxPercentageConfig-r16 ::= SEQUENCE { + sl-Priority-r16 INTEGER (1..8), + sl-TxPercentage-r16 ENUMERATED {p20, p35, p50} +} + +SL-MinMaxMCS-List-r16 ::= SEQUENCE (SIZE (1..3)) OF SL-MinMaxMCS-Config-r16 + +SL-MinMaxMCS-Config-r16 ::= SEQUENCE { + sl-MCS-Table-r16 ENUMERATED {qam64, qam256, qam64LowSE}, + sl-MinMCS-PSSCH-r16 INTEGER (0..27), + sl-MaxMCS-PSSCH-r16 INTEGER (0..31) +} + +SL-BetaOffsets-r16 ::= INTEGER (0..31) + +SL-PowerControl-r16 ::= SEQUENCE { + sl-MaxTransPower-r16 INTEGER (-30..33), + sl-Alpha-PSSCH-PSCCH-r16 ENUMERATED {alpha0, alpha04, alpha05, alpha06, alpha07, alpha08, alpha09, alpha1} OPTIONAL, -- Need M + dl-Alpha-PSSCH-PSCCH-r16 ENUMERATED {alpha0, alpha04, alpha05, alpha06, alpha07, alpha08, alpha09, alpha1} OPTIONAL, -- Need M + sl-P0-PSSCH-PSCCH-r16 INTEGER (-16..15) OPTIONAL, -- Need M + dl-P0-PSSCH-PSCCH-r16 INTEGER (-16..15) OPTIONAL, -- Need M + dl-Alpha-PSFCH-r16 ENUMERATED {alpha0, alpha04, alpha05, alpha06, alpha07, alpha08, alpha09, alpha1} OPTIONAL, -- Need M + dl-P0-PSFCH-r16 INTEGER (-16..15) OPTIONAL, -- Need M + ... +} + +-- TAG-SL-RESOURCEPOOL-STOP +-- TAG-SL-RLC-BEARERCONFIG-START + +SL-RLC-BearerConfig-r16 ::= SEQUENCE { + sl-RLC-BearerConfigIndex-r16 SL-RLC-BearerConfigIndex-r16, + sl-ServedRadioBearer-r16 SLRB-Uu-ConfigIndex-r16 OPTIONAL, -- Cond LCH-SetupOnly + sl-RLC-Config-r16 SL-RLC-Config-r16 OPTIONAL, -- Cond LCH-Setup + sl-MAC-LogicalChannelConfig-r16 SL-LogicalChannelConfig-r16 OPTIONAL, -- Cond LCH-Setup + ... +} + +-- TAG-SL-RLC-BEARERCONFIG-STOP +-- TAG-SL-RLC-BEARERCONFIGINDEX-START + +SL-RLC-BearerConfigIndex-r16 ::= INTEGER (1..maxSL-LCID-r16) + +-- TAG-RLC-BEARERCONFIGINDEX-STOP +-- TAG-SL-RLC-CONFIG-START + +SL-RLC-Config-r16 ::= CHOICE { + sl-AM-RLC-r16 SEQUENCE { + sl-SN-FieldLengthAM-r16 SN-FieldLengthAM OPTIONAL, -- Cond SLRBSetup + sl-T-PollRetransmit-r16 T-PollRetransmit, + sl-PollPDU-r16 PollPDU, + sl-PollByte-r16 PollByte, + sl-MaxRetxThreshold-r16 ENUMERATED { t1, t2, t3, t4, t6, t8, t16, t32 }, + ... + }, + sl-UM-RLC-r16 SEQUENCE { + sl-SN-FieldLengthUM-r16 SN-FieldLengthUM OPTIONAL, -- Cond SLRBSetup + ... + }, + ... +} + +-- TAG-SL-RLC-CONFIG-STOP +-- TAG-SL-SCHEDULEDCONFIG-START + +SL-ScheduledConfig-r16 ::= SEQUENCE { + sl-RNTI-r16 RNTI-Value, + mac-MainConfigSL-r16 MAC-MainConfigSL-r16 OPTIONAL, -- Need M + sl-Timing-Config-r16 SL-TimingConfig-r16 OPTIONAL, -- Need M + sl-CS-RNTI-r16 RNTI-Value OPTIONAL, -- Need M + sl-PSFCH-ToPUCCH-r16 SEQUENCE (SIZE (1..8)) OF INTEGER (0..15) OPTIONAL, -- Need M + sl-ConfiguredGrantConfigList-r16 SL-ConfiguredGrantConfigList-r16 OPTIONAL, -- Need M + ... +} + +MAC-MainConfigSL-r16 ::= SEQUENCE { + sl-BSR-Config-r16 BSR-Config OPTIONAL, -- Need M + ul-PrioritizationThres-r16 INTEGER (1..16) OPTIONAL, -- Need M + sl-PrioritizationThres-r16 INTEGER (1..8) OPTIONAL, -- Need M + ... + +} + +SL-TimingConfig-r16 ::= SEQUENCE { + sl-DCI-ToSL-Trans-r16 ENUMERATED{ffs} OPTIONAL, -- Need M + ... +} + +SL-ConfiguredGrantConfigList-r16 ::= SEQUENCE { + sl-ConfiguredGrantConfigToReleaseList-r16 SEQUENCE (SIZE (1..maxNrofCG-SL-r16)) OF SL-ConfigIndexCG-r16 OPTIONAL, -- Need N + sl-ConfiguredGrantConfigToAddModList-r16 SEQUENCE (SIZE (1..maxNrofCG-SL-r16)) OF SL-ConfiguredGrantConfig-r16 OPTIONAL -- Need N +} + +-- TAG-SL-SCHEDULEDCONFIG-STOP +-- TAG-SL-SDAP-CONFIG-START + +SL-SDAP-Config-r16 ::= SEQUENCE { + sl-SDAP-Header-r16 ENUMERATED {present, absent}, + sl-DefaultRB-r16 BOOLEAN, + sl-MappedQoS-Flows-r16 CHOICE { + sl-MappedQoS-FlowsList-r16 SEQUENCE (SIZE (1..maxNrofSL-QFIs-r16)) OF SL-QoS-Profile-r16, + sl-MappedQoS-FlowsListDedicated-r16 SL-MappedQoS-FlowsListDedicated-r16 + } OPTIONAL, -- Need M + sl-CastType-r16 ENUMERATED {broadcast, groupcast, unicast, spare1} OPTIONAL, -- Need M + ... +} + +SL-MappedQoS-FlowsListDedicated-r16 ::= SEQUENCE { + sl-MappedQoS-FlowsToAddList-r16 SEQUENCE (SIZE (1..maxNrofSL-QFIs-r16)) OF SL-QoS-FlowIdentity-r16 OPTIONAL, -- Need N + sl-MappedQoS-FlowsToReleaseList-16 SEQUENCE (SIZE (1..maxNrofSL-QFIs-r16)) OF SL-QoS-FlowIdentity-r16 OPTIONAL -- Need N +} + +-- TAG-SL-SDAP-CONFIG-STOP +-- TAG-SL-SYNCCONFIG-START + +SL-SyncConfigList-r16 ::= SEQUENCE (SIZE (1..maxSL-SyncConfig-r16)) OF SL-SyncConfig-r16 + +SL-SyncConfig-r16 ::= SEQUENCE { + sl-SyncRefMinHyst-r16 ENUMERATED {dB0, dB3, dB6, dB9, dB12} OPTIONAL, -- Need R + sl-SyncRefDiffHyst-r16 ENUMERATED {dB0, dB3, dB6, dB9, dB12, dBinf} OPTIONAL, -- Need R + sl-filterCoefficient-r16 FilterCoefficient OPTIONAL, -- Need R + sl-SSB-TimeAllocation1-r16 SL-SSB-TimeAllocation-r16 OPTIONAL, -- Need R + sl-SSB-TimeAllocation2-r16 SL-SSB-TimeAllocation-r16 OPTIONAL, -- Need R + sl-SSB-TimeAllocation3-r16 SL-SSB-TimeAllocation-r16 OPTIONAL, -- Need R + sl-SSID-r16 INTEGER (0..671) OPTIONAL, -- Need R + txParameters-r16 SEQUENCE { + syncTxThreshIC-r16 SL-RSRP-Range-r16 OPTIONAL, -- Need R + syncTxThreshOoC-r16 SL-RSRP-Range-r16 OPTIONAL, -- Need R + syncInfoReserved-r16 BIT STRING (SIZE (2)) OPTIONAL -- Need R + }, + gnss-Sync-r16 ENUMERATED {true} OPTIONAL, -- Need R +... +} + +SL-RSRP-Range-r16 ::= INTEGER (0..13) + +SL-SSB-TimeAllocation-r16 ::= SEQUENCE { + sl-NumSSB-WithinPeriod-r16 ENUMERATED {n1, n2, n4, n5, n16, n32, n64} OPTIONAL, -- Need R + sl-TimeOffsetSSB-r16 INTEGER (0..1279) OPTIONAL, -- Need R + sl-TimeInterval-r16 INTEGER (0..639) OPTIONAL -- Need R +} + +-- TAG-SL-SYNCCONFIG-STOP +-- TAG-SL-THRESPSSCH-RSRP-LIST-START + +SL-ThresPSSCH-RSRP-List-r16 ::= SEQUENCE (SIZE (64)) OF SL-ThresPSSCH-RSRP-r16 + +SL-ThresPSSCH-RSRP-r16 ::= INTEGER (0..66) + +-- TAG-SL-THRESPSSCH-RSRP-LIST-STOP +-- TAG-SL-TXPOWER-START + +SL-TxPower-r16 ::= CHOICE{ + minusinfinity-r16 NULL, + txPower-r16 INTEGER (-30..33) +} + +-- TAG-SL-TXPOWER-STOP +-- TAG-SL-TYPETXSYNC-START + +SL-TypeTxSync-r16 ::= ENUMERATED {gnss, gnbEnb, ue} + +-- TAG-SL-TYPETXSYNC-STOP +-- TAG-SL-UE-SELECTEDCONFIG-START + +SL-UE-SelectedConfig-r16 ::= SEQUENCE { + sl-PSSCH-TxConfigList-r16 SL-PSSCH-TxConfigList-r16 OPTIONAL, -- Need R + sl-ProbResourceKeep-r16 ENUMERATED {v0, v0dot2, v0dot4, v0dot6, v0dot8} OPTIONAL, -- Need R + sl-ReselectAfter-r16 ENUMERATED {n1, n2, n3, n4, n5, n6, n7, n8, n9} OPTIONAL, -- Need R + sl-CBR-CommonTxConfigList-r16 SL-CBR-CommonTxConfigList-r16 OPTIONAL, -- Need R + ul-PrioritizationThres-r16 INTEGER (1..16) OPTIONAL, -- Need R + sl-PrioritizationThres-r16 INTEGER (1..8) OPTIONAL, -- Need R + ... +} + +-- TAG-SL-UE-SELECTEDCONFIG-STOP +-- TAG-SL-ZONECONFIG-START + +SL-ZoneConfig-r16 ::= SEQUENCE { + sl-ZoneLength-r16 ENUMERATED { m5, m10, m20, m30, m40, m50, spare2, spare1}, + ... +} + +-- TAG-SL-ZONECONFIG-STOP +-- TAG-SLRB-UU-CONFIGINDEX-START + +SLRB-Uu-ConfigIndex-r16 ::= INTEGER (1..maxNrofSLRB-r16) + +-- TAG-SLRB-UU-CONFIGINDEX-STOP +-- TAG-MULTIPLICITY-AND-TYPE-CONSTRAINT-DEFINITIONS-START + +maxAI-DCI-PayloadSize-r16 INTEGER ::= 128 --Maximum size of the DCI payload scrambled with ai-RNTI +maxAI-DCI-PayloadSize-r16-1 INTEGER ::= 127 --Maximum size of the DCI payload scrambled with ai-RNTI minus 1 +maxBandComb INTEGER ::= 65536 -- Maximum number of DL band combinations +maxBandsUTRA-FDD-r16 INTEGER ::= 64 -- Maximum number of bands listed in UTRA-FDD UE caps +maxBH-RLC-ChannelID-r16 INTEGER ::= 65536 -- Maximum value of BH RLC Channel ID +maxBT-IdReport-r16 INTEGER ::= 32 -- Maximum number of Bluetooth IDs to report +maxBT-Name-r16 INTEGER ::= 4 -- Maximum number of Bluetooth name +maxCAG-Cell-r16 INTEGER ::= 16 -- Maximum number of NR CAG cell ranges in SIB3, SIB4 +maxCBR-Config-r16 INTEGER ::= 8 -- Maximum number of CBR range configurations for sidelink communication + -- congestion control +maxCBR-Config-1-r16 INTEGER ::= 7 -- Maximum number of CBR range configurations for sidelink communication + -- congestion control minus 1 +maxCBR-Level-r16 INTEGER ::= 16 -- Maximum nuber of CBR levels +maxCBR-Level-1-r16 INTEGER ::= 15 -- Maximum number of CBR levels minus 1 +maxCellBlack INTEGER ::= 16 -- Maximum number of NR blacklisted cell ranges in SIB3, SIB4 +maxCellHistory-r16 INTEGER ::= 16 -- Maximum number of visited cells reported +maxCellInter INTEGER ::= 16 -- Maximum number of inter-Freq cells listed in SIB4 +maxCellIntra INTEGER ::= 16 -- Maximum number of intra-Freq cells listed in SIB3 +maxCellMeasEUTRA INTEGER ::= 32 -- Maximum number of cells in E-UTRAN +maxCellMeasIdle-r16 INTEGER ::= 8 -- Maximum number of cells per carrier for idle/inactive measurements +maxCellMeasUTRA-FDD-r16 INTEGER ::= 32 -- Maximum number of cells in FDD UTRAN +maxCellWhite INTEGER ::= 16 -- Maximum number of NR whitelisted cell ranges in SIB3, SIB4 +maxEARFCN INTEGER ::= 262143 -- Maximum value of E-UTRA carrier frequency +maxEUTRA-CellBlack INTEGER ::= 16 -- Maximum number of E-UTRA blacklisted physical cell identity ranges + -- in SIB5 +maxEUTRA-NS-Pmax INTEGER ::= 8 -- Maximum number of NS and P-Max values per band +maxLogMeasReport-r16 INTEGER ::= 520 -- Maximum number of entries for logged measurements +maxMultiBands INTEGER ::= 8 -- Maximum number of additional frequency bands that a cell belongs to +maxNARFCN INTEGER ::= 3279165 -- Maximum value of NR carrier frequency +maxNR-NS-Pmax INTEGER ::= 8 -- Maximum number of NS and P-Max values per band +maxFreqIdle-r16 INTEGER ::= 8 -- Maximum number of carrier frequencies for idle/inactive measurements +maxNrofServingCells INTEGER ::= 32 -- Max number of serving cells (SpCells + SCells) +maxNrofServingCells-1 INTEGER ::= 31 -- Max number of serving cells (SpCell + SCells) per cell group +maxNrofAggregatedCellsPerCellGroup INTEGER ::= 16 +maxNrofDUCells-r16 INTEGER ::= 512 -- Max number of cells configured on the collocated IAB-DU +maxNrofAssociatedDUCellsPerMT-r16 INTEGER ::= 65535 +maxNrofAvailabilityCombinationsPerSet-r16 INTEGER ::= 512 -- Max number of AvailabilityCombinationId used in the DCI format 2_5 +maxNrofAvailabilityCombinationsPerSet-r16-1 INTEGER ::= 511 -- Max number of AvailabilityCombinationId used in the DCI format 2_5 minus 1 +maxNrofSCells INTEGER ::= 31 -- Max number of secondary serving cells per cell group +maxNrofCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the cell lists in a measurement object +maxNrofCG-SL-r16 INTEGER ::= 8 -- Max number of sidelink configured grant +maxNrofCG-SL-r16-1 INTEGER ::= 7 -- Max number of sidelink configured grant minus 1 +maxNrofSS-BlocksToAverage INTEGER ::= 16 -- Max number for the (max) number of SS blocks to average to determine cell measurement +maxNrofCondCells-r16 INTEGER ::= 8 -- Max number of conditional candidate SpCells +maxNrofCSI-RS-ResourcesToAverage INTEGER ::= 16 -- Max number for the (max) number of CSI-RS to average to determine cell measurement +maxNrofDL-Allocations INTEGER ::= 16 -- Maximum number of PDSCH time domain resource allocations +maxNrofSR-ConfigPerCellGroup INTEGER ::= 8 -- Maximum number of SR configurations per cell group +maxLCG-ID INTEGER ::= 7 -- Maximum value of LCG ID +maxLC-ID INTEGER ::= 32 -- Maximum value of Logical Channel ID +maxLC-ID-Iab-r16 INTEGER ::= 65536 -- Maximum value of BH Logical Channel ID extension +maxLTE-CRS-Patterns-r16 INTEGER ::= 3 -- Maximum number of additional LTE CRS rate matching patterns +maxNrofTAGs INTEGER ::= 4 -- Maximum number of Timing Advance Groups +maxNrofTAGs-1 INTEGER ::= 3 -- Maximum number of Timing Advance Groups minus 1 +maxNrofBWPs INTEGER ::= 4 -- Maximum number of BWPs per serving cell +maxNrofCombIDC INTEGER ::= 128 -- Maximum number of reported MR-DC combinations for IDC +maxNrofSymbols-1 INTEGER ::= 13 -- Maximum index identifying a symbol within a slot (14 symbols, indexed from 0..13) +maxNrofSlots INTEGER ::= 320 -- Maximum number of slots in a 10 ms period +maxNrofSlots-1 INTEGER ::= 319 -- Maximum number of slots in a 10 ms period minus 1 +maxNrofPhysicalResourceBlocks INTEGER ::= 275 -- Maximum number of PRBs +maxNrofPhysicalResourceBlocks-1 INTEGER ::= 274 -- Maximum number of PRBs minus 1 +maxNrofPhysicalResourceBlocksPlus1 INTEGER ::= 276 -- Maximum number of PRBs plus 1 +maxNrofControlResourceSets INTEGER ::= 12 -- Max number of CoReSets configurable on a serving cell +maxNrofControlResourceSets-1 INTEGER ::= 11 -- Max number of CoReSets configurable on a serving cell minus 1 +maxNrofControlResourceSets-1-r16 INTEGER ::= 15 -- Max number of CoReSets configurable on a serving cell extended in minus 1 +maxNrofCoresetPools-r16 INTEGER ::= 2 -- Maximum number of CORESET pools +maxCoReSetDuration INTEGER ::= 3 -- Max number of OFDM symbols in a control resource set +maxNrofSearchSpaces-1 INTEGER ::= 39 -- Max number of Search Spaces minus 1 +maxSFI-DCI-PayloadSize INTEGER ::= 128 -- Max number payload of a DCI scrambled with SFI-RNTI +maxSFI-DCI-PayloadSize-1 INTEGER ::= 127 -- Max number payload of a DCI scrambled with SFI-RNTI minus 1 +maxIAB-IP-Address-r16 INTEGER ::= 32 -- Max number of assigned IP addresses +maxINT-DCI-PayloadSize INTEGER ::= 126 -- Max number payload of a DCI scrambled with INT-RNTI +maxINT-DCI-PayloadSize-1 INTEGER ::= 125 -- Max number payload of a DCI scrambled with INT-RNTI minus 1 +maxNrofRateMatchPatterns INTEGER ::= 4 -- Max number of rate matching patterns that may be configured +maxNrofRateMatchPatterns-1 INTEGER ::= 3 -- Max number of rate matching patterns that may be configured minus 1 +maxNrofRateMatchPatternsPerGroup INTEGER ::= 8 -- Max number of rate matching patterns that may be configured in one group +maxNrofCSI-ReportConfigurations INTEGER ::= 48 -- Maximum number of report configurations +maxNrofCSI-ReportConfigurations-1 INTEGER ::= 47 -- Maximum number of report configurations minus 1 +maxNrofCSI-ResourceConfigurations INTEGER ::= 112 -- Maximum number of resource configurations +maxNrofCSI-ResourceConfigurations-1 INTEGER ::= 111 -- Maximum number of resource configurations minus 1 +maxNrofAP-CSI-RS-ResourcesPerSet INTEGER ::= 16 +maxNrOfCSI-AperiodicTriggers INTEGER ::= 128 -- Maximum number of triggers for aperiodic CSI reporting +maxNrofReportConfigPerAperiodicTrigger INTEGER ::= 16 -- Maximum number of report configurations per trigger state for aperiodic reporting +maxNrofNZP-CSI-RS-Resources INTEGER ::= 192 -- Maximum number of Non-Zero-Power (NZP) CSI-RS resources +maxNrofNZP-CSI-RS-Resources-1 INTEGER ::= 191 -- Maximum number of Non-Zero-Power (NZP) CSI-RS resources minus 1 +maxNrofNZP-CSI-RS-ResourcesPerSet INTEGER ::= 64 -- Maximum number of NZP CSI-RS resources per resource set +maxNrofNZP-CSI-RS-ResourceSets INTEGER ::= 64 -- Maximum number of NZP CSI-RS resources per cell +maxNrofNZP-CSI-RS-ResourceSets-1 INTEGER ::= 63 -- Maximum number of NZP CSI-RS resources per cell minus 1 +maxNrofNZP-CSI-RS-ResourceSetsPerConfig INTEGER ::= 16 -- Maximum number of resource sets per resource configuration +maxNrofNZP-CSI-RS-ResourcesPerConfig INTEGER ::= 128 -- Maximum number of resources per resource configuration +maxNrofZP-CSI-RS-Resources INTEGER ::= 32 -- Maximum number of Zero-Power (ZP) CSI-RS resources +maxNrofZP-CSI-RS-Resources-1 INTEGER ::= 31 -- Maximum number of Zero-Power (ZP) CSI-RS resources minus 1 +maxNrofZP-CSI-RS-ResourceSets-1 INTEGER ::= 15 +maxNrofZP-CSI-RS-ResourcesPerSet INTEGER ::= 16 +maxNrofZP-CSI-RS-ResourceSets INTEGER ::= 16 +maxNrofCSI-IM-Resources INTEGER ::= 32 -- Maximum number of CSI-IM resources. See CSI-IM-ResourceMax in 38.214. +maxNrofCSI-IM-Resources-1 INTEGER ::= 31 -- Maximum number of CSI-IM resources minus 1. See CSI-IM-ResourceMax in 38.214. +maxNrofCSI-IM-ResourcesPerSet INTEGER ::= 8 -- Maximum number of CSI-IM resources per set. See CSI-IM-ResourcePerSetMax in 38.214 +maxNrofCSI-IM-ResourceSets INTEGER ::= 64 -- Maximum number of NZP CSI-IM resources per cell +maxNrofCSI-IM-ResourceSets-1 INTEGER ::= 63 -- Maximum number of NZP CSI-IM resources per cell minus 1 +maxNrofCSI-IM-ResourceSetsPerConfig INTEGER ::= 16 -- Maximum number of CSI IM resource sets per resource configuration +maxNrofCSI-SSB-ResourcePerSet INTEGER ::= 64 -- Maximum number of SSB resources in a resource set +maxNrofCSI-SSB-ResourceSets INTEGER ::= 64 -- Maximum number of CSI SSB resource sets per cell +maxNrofCSI-SSB-ResourceSets-1 INTEGER ::= 63 -- Maximum number of CSI SSB resource sets per cell minus 1 +maxNrofCSI-SSB-ResourceSetsPerConfig INTEGER ::= 1 -- Maximum number of CSI SSB resource sets per resource configuration +maxNrofFailureDetectionResources INTEGER ::= 10 -- Maximum number of failure detection resources +maxNrofFailureDetectionResources-1 INTEGER ::= 9 -- Maximum number of failure detection resources minus 1 +maxNrofFreqSL-r16 INTEGER ::= 8 -- Maximum number of carrier frequncy for for NR sidelink communication +maxNrofSL-BWPs-r16 INTEGER ::= 4 -- Maximum number of BWP for for NR sidelink communication +maxFreqSL-EUTRA-r16 INTEGER ::= 8 -- Maximum number of EUTRA anchor carrier frequncy for NR sidelink communication +maxNrofSL-MeasId-r16 INTEGER ::= 64 -- Maximum number of sidelink measurement identity (RSRP) per destination +maxNrofSL-ObjectId-r16 INTEGER ::= 64 -- Maximum number of sidelink measurement objects (RSRP) per destination +maxNrofSL-ReportConfigId-r16 INTEGER ::= 64 -- Maximum number of sidelink measurement reporting configuration(RSRP) per destination +maxNrofSL-PoolToMeasureNR-r16 INTEGER ::= 8 -- Maximum number of resoure pool for NR sidelink measurement to measure for + -- each measurement object (for CBR) +maxFreqSL-NR-r16 INTEGER ::= 8 -- Maximum number of NR anchor carrier frequncy for NR sidelink communication +maxNrofSL-QFIs-r16 INTEGER ::= 2048 -- Maximum number of QoS flow for NR sidelink communication per UE +maxNrofSL-QFIsPerDest-r16 INTEGER ::= 64 -- Maximum number of QoS flow per destination for NR sidelink communication +maxNrofObjectId INTEGER ::= 64 -- Maximum number of measurement objects +maxNrofPageRec INTEGER ::= 32 -- Maximum number of page records +maxNrofPCI-Ranges INTEGER ::= 8 -- Maximum number of PCI ranges +maxPLMN INTEGER ::= 12 -- Maximum number of PLMNs broadcast and reported by UE at establisghment +maxNrofCSI-RS-ResourcesRRM INTEGER ::= 96 -- Maximum number of CSI-RS resources for an RRM measurement object +maxNrofCSI-RS-ResourcesRRM-1 INTEGER ::= 95 -- Maximum number of CSI-RS resources for an RRM measurement object minus 1 +maxNrofMeasId INTEGER ::= 64 -- Maximum number of configured measurements +maxNrofQuantityConfig INTEGER ::= 2 -- Maximum number of quantity configurations +maxNrofCSI-RS-CellsRRM INTEGER ::= 96 -- Maximum number of cells with CSI-RS resources for an RRM measurement object +maxNrofSL-Dest-r16 INTEGER ::= 32 -- Maximum number of destination for NR sidelink communication +maxNrofSL-Dest-1-r16 INTEGER ::= 31 -- Highest index of destination for NR sidelink communication +maxNrofSLRB-r16 INTEGER ::= 512 -- Maximum number of radio bearer for NR sidelink communication per UE +maxSL-LCID-r16 INTEGER ::= 512 -- Maximum number of RLC bearer for NR sidelink communication per UE +maxSL-SyncConfig-r16 INTEGER ::= 16 -- Maximum number of sidelink Sync configurations +maxNrofRXPool-r16 INTEGER ::= 16 -- Maximum number of Rx resource poolfor NR sidelink communication +maxNrofTXPool-r16 INTEGER ::= 8 -- Maximum number of Tx resourcepoolfor NR sidelink communication +maxNrofPoolID-r16 INTEGER ::= 16 -- Maximum index of resource pool for NR sidelink communication +maxNrofSRS-PathlossReferenceRS-r16 INTEGER ::= 64 -- Maximum number of RSs used as pathloss reference for SRS power control. +maxNrofSRS-PathlossReferenceRS-1-r16 INTEGER ::= 63 -- Maximum number of RSs used as pathloss reference for SRS power control-1. +maxNrofSRS-ResourceSets INTEGER ::= 16 -- Maximum number of SRS resource sets in a BWP. +maxNrofSRS-ResourceSets-1 INTEGER ::= 15 -- Maximum number of SRS resource sets in a BWP minus 1. +maxNrofSRS-PosResourceSets-r16 INTEGER ::= 16 -- Maximum number of SRS Positioning resource sets in a BWP. +maxNrofSRS-PosResourceSets-1-r16 INTEGER ::= 15 -- Maximum number of SRS Positioning resource sets in a BWP minus 1. +maxNrofSRS-Resources INTEGER ::= 64 -- Maximum number of SRS resources. +maxNrofSRS-Resources-1 INTEGER ::= 63 -- Maximum number of SRS resources in an SRS resource set minus 1. +maxNrofSRS-PosResources-r16 INTEGER ::= 64 -- Maximum number of SRS Positioning resources. +maxNrofSRS-PosResources-1-r16 INTEGER ::= 63 -- Maximum number of SRS Positioning resources in an SRS Positioning + -- resource set minus 1. +maxNrofSRS-ResourcesPerSet INTEGER ::= 16 -- Maximum number of SRS resources in an SRS resource set +maxNrofSRS-TriggerStates-1 INTEGER ::= 3 -- Maximum number of SRS trigger states minus 1, i.e., the largest code point. +maxNrofSRS-TriggerStates-2 INTEGER ::= 2 -- Maximum number of SRS trigger states minus 2. +maxRAT-CapabilityContainers INTEGER ::= 8 -- Maximum number of interworking RAT containers (incl NR and MRDC) +maxSimultaneousBands INTEGER ::= 32 -- Maximum number of simultaneously aggregated bands +maxULTxSwitchingBandPairs INTEGER ::= 32 -- Maximum number of band pairs supporting dynamic UL Tx switching in a band combination +maxNrofSlotFormatCombinationsPerSet INTEGER ::= 512 -- Maximum number of Slot Format Combinations in a SF-Set. +maxNrofSlotFormatCombinationsPerSet-1 INTEGER ::= 511 -- Maximum number of Slot Format Combinations in a SF-Set minus 1. +maxNrofTrafficPattern-r16 INTEGER ::= 8 -- Maximum number of Traffic Pattern for NR sidelink communication. +maxNrofPUCCH-Resources INTEGER ::= 128 +maxNrofPUCCH-Resources-1 INTEGER ::= 127 +maxNrofPUCCH-ResourceSets INTEGER ::= 4 -- Maximum number of PUCCH Resource Sets +maxNrofPUCCH-ResourceSets-1 INTEGER ::= 3 -- Maximum number of PUCCH Resource Sets minus 1. +maxNrofPUCCH-ResourcesPerSet INTEGER ::= 32 -- Maximum number of PUCCH Resources per PUCCH-ResourceSet +maxNrofPUCCH-P0-PerSet INTEGER ::= 8 -- Maximum number of P0-pucch present in a p0-pucch set +maxNrofPUCCH-PathlossReferenceRSs INTEGER ::= 4 -- Maximum number of RSs used as pathloss reference for PUCCH power control. +maxNrofPUCCH-PathlossReferenceRSs-1 INTEGER ::= 3 -- Maximum number of RSs used as pathloss reference for PUCCH power control minus 1. +maxNrofPUCCH-PathlossReferenceRSs-r16 INTEGER ::= 64 -- Maximum number of RSs used as pathloss reference for PUCCH power control extended. +maxNrofPUCCH-PathlossReferenceRSs-1-r16 INTEGER ::= 63 -- Maximum number of RSs used as pathloss reference for PUCCH power control + -- minus 1 extended. +maxNrofPUCCH-PathlossReferenceRSsDiff-r16 INTEGER ::= 60 -- Difference between the extended maximum and the non-extended maximum +maxNrofPUCCH-ResourceGroups-r16 INTEGER ::= 4 -- Maximum number of PUCCH resources groups. +maxNrofPUCCH-ResourcesPerGroup-r16 INTEGER ::= 128 -- Maximum number of PUCCH resources in a PUCCH group. +maxNrofMultiplePUSCHs-r16 INTEGER ::= 8 -- Maximum number of multiple PUSCHs in PUSCH TDRA list +maxNrofP0-PUSCH-AlphaSets INTEGER ::= 30 -- Maximum number of P0-pusch-alpha-sets (see 38,213, clause 7.1) +maxNrofP0-PUSCH-AlphaSets-1 INTEGER ::= 29 -- Maximum number of P0-pusch-alpha-sets minus 1 (see 38,213, clause 7.1) +maxNrofPUSCH-PathlossReferenceRSs INTEGER ::= 4 -- Maximum number of RSs used as pathloss reference for PUSCH power control. +maxNrofPUSCH-PathlossReferenceRSs-1 INTEGER ::= 3 -- Maximum number of RSs used as pathloss reference for PUSCH power control minus 1. +maxNrofPUSCH-PathlossReferenceRSs-r16 INTEGER ::= 64 -- Maximum number of RSs used as pathloss reference for PUSCH power control extended +maxNrofPUSCH-PathlossReferenceRSs-1-r16 INTEGER ::= 63 -- Maximum number of RSs used as pathloss reference for PUSCH power control minus 1 +maxNrofPUSCH-PathlossReferenceRSsDiff-r16 INTEGER ::= 60 -- Difference between maxNrofPUSCH-PathlossReferenceRSs-r16 and + -- maxNrofPUSCH-PathlossReferenceRSs +maxNrofNAICS-Entries INTEGER ::= 8 -- Maximum number of supported NAICS capability set +maxBands INTEGER ::= 1024 -- Maximum number of supported bands in UE capability. +maxBandsMRDC INTEGER ::= 1280 +maxBandsEUTRA INTEGER ::= 256 +maxCellReport INTEGER ::= 8 +maxDRB INTEGER ::= 29 -- Maximum number of DRBs (that can be added in DRB-ToAddModLIst). +maxFreq INTEGER ::= 8 -- Max number of frequencies. +maxFreqLayers INTEGER ::= 4 -- Max number of frequency layers. +maxFreqIDC-r16 INTEGER ::= 128 -- Max number of frequencies for IDC indication. +maxCombIDC-r16 INTEGER ::= 128 -- Max number of reported UL CA for IDC indication. +maxFreqIDC-MRDC INTEGER ::= 32 -- Maximum number of candidate NR frequencies for MR-DC IDC indication +maxNrofCandidateBeams INTEGER ::= 16 -- Max number of PRACH-ResourceDedicatedBFR that in BFR config. +maxNrofCandidateBeams-r16 INTEGER ::= 64 -- Max number of candidate beam resources in BFR config. +maxNrofCandidateBeamsExt-r16 INTEGER ::= 48 -- Max number of PRACH-ResourceDedicatedBFR in the CandidateBeamRSListExt +maxNrofPCIsPerSMTC INTEGER ::= 64 -- Maximun number of PCIs per SMTC. +maxNrofQFIs INTEGER ::= 64 +maxNrofResourceAvailabilityPerCombination-r16 INTEGER ::= 256 +maxNrOfSemiPersistentPUSCH-Triggers INTEGER ::= 64 -- Maximum number of triggers for semi persistent reporting on PUSCH +maxNrofSR-Resources INTEGER ::= 8 -- Maximum number of SR resources per BWP in a cell. +maxNrofSlotFormatsPerCombination INTEGER ::= 256 +maxNrofSpatialRelationInfos INTEGER ::= 8 +maxNrofSpatialRelationInfos-plus-1 INTEGER ::= 9 +maxNrofSpatialRelationInfos-r16 INTEGER ::= 64 +maxNrofSpatialRelationInfosDiff-r16 INTEGER ::= 56 -- Difference between maxNrofSpatialRelationInfos-r16 and maxNrofSpatialRelationInfos +maxNrofIndexesToReport INTEGER ::= 32 +maxNrofIndexesToReport2 INTEGER ::= 64 +maxNrofSSBs-r16 INTEGER ::= 64 -- Maximum number of SSB resources in a resource set. +maxNrofSSBs-1 INTEGER ::= 63 -- Maximum number of SSB resources in a resource set minus 1. +maxNrofS-NSSAI INTEGER ::= 8 -- Maximum number of S-NSSAI. +maxNrofTCI-StatesPDCCH INTEGER ::= 64 +maxNrofTCI-States INTEGER ::= 128 -- Maximum number of TCI states. +maxNrofTCI-States-1 INTEGER ::= 127 -- Maximum number of TCI states minus 1. +maxNrofUL-Allocations INTEGER ::= 16 -- Maximum number of PUSCH time domain resource allocations. +maxQFI INTEGER ::= 63 +maxRA-CSIRS-Resources INTEGER ::= 96 +maxRA-OccasionsPerCSIRS INTEGER ::= 64 -- Maximum number of RA occasions for one CSI-RS +maxRA-Occasions-1 INTEGER ::= 511 -- Maximum number of RA occasions in the system +maxRA-SSB-Resources INTEGER ::= 64 +maxSCSs INTEGER ::= 5 +maxSecondaryCellGroups INTEGER ::= 3 +maxNrofServingCellsEUTRA INTEGER ::= 32 +maxMBSFN-Allocations INTEGER ::= 8 +maxNrofMultiBands INTEGER ::= 8 +maxCellSFTD INTEGER ::= 3 -- Maximum number of cells for SFTD reporting +maxReportConfigId INTEGER ::= 64 +maxNrofCodebooks INTEGER ::= 16 -- Maximum number of codebooks suppoted by the UE +maxNrofCSI-RS-Resources INTEGER ::= 7 -- Maximum number of codebook resources supported by the UE +maxNrofCSI-RS-ResourcesAlt-r16 INTEGER ::= 512 -- Maximum number of alternative codebook resources supported by the UE +maxNrofCSI-RS-ResourcesAlt-1-r16 INTEGER ::= 511 -- Maximum number of alternative codebook resources supported by the UE minus 1 +maxNrofSRI-PUSCH-Mappings INTEGER ::= 16 +maxNrofSRI-PUSCH-Mappings-1 INTEGER ::= 15 +maxSIB INTEGER::= 32 -- Maximum number of SIBs +maxSI-Message INTEGER::= 32 -- Maximum number of SI messages +maxPO-perPF INTEGER ::= 4 -- Maximum number of paging occasion per paging frame +maxAccessCat-1 INTEGER ::= 63 -- Maximum number of Access Categories minus 1 +maxBarringInfoSet INTEGER ::= 8 -- Maximum number of Access Categories +maxCellEUTRA INTEGER ::= 8 -- Maximum number of E-UTRA cells in SIB list +maxEUTRA-Carrier INTEGER ::= 8 -- Maximum number of E-UTRA carriers in SIB list +maxPLMNIdentities INTEGER ::= 8 -- Maximum number of PLMN identites in RAN area configurations +maxDownlinkFeatureSets INTEGER ::= 1024 -- (for NR DL) Total number of FeatureSets (size of the pool) +maxUplinkFeatureSets INTEGER ::= 1024 -- (for NR UL) Total number of FeatureSets (size of the pool) +maxEUTRA-DL-FeatureSets INTEGER ::= 256 -- (for E-UTRA) Total number of FeatureSets (size of the pool) +maxEUTRA-UL-FeatureSets INTEGER ::= 256 -- (for E-UTRA) Total number of FeatureSets (size of the pool) +maxFeatureSetsPerBand INTEGER ::= 128 -- (for NR) The number of feature sets associated with one band. +maxPerCC-FeatureSets INTEGER ::= 1024 -- (for NR) Total number of CC-specific FeatureSets (size of the pool) +maxFeatureSetCombinations INTEGER ::= 1024 -- (for MR-DC/NR)Total number of Feature set combinations (size of the pool) +maxInterRAT-RSTD-Freq INTEGER ::= 3 +maxHRNN-Len-r16 INTEGER ::= 48 -- Maximum length of HRNNs +maxNPN-r16 INTEGER ::= 12 -- Maximum number of NPNs broadcast and reported by UE at establishment +maxNrOfMinSchedulingOffsetValues-r16 INTEGER ::= 2 -- Maximum number of min. scheduling offset (K0/K2) configurations +maxK0-SchedulingOffset-r16 INTEGER ::= 16 -- Maximum number of slots configured as min. scheduling offset (K0) +maxK2-SchedulingOffset-r16 INTEGER ::= 16 -- Maximum number of slots configured as min. scheduling offset (K2) +maxDCI-2-6-Size-r16 INTEGER ::= 140 -- Maximum size of DCI format 2-6 +maxDCI-2-6-Size-1-r16 INTEGER ::= 139 -- Maximum DCI format 2-6 size minus 1 +maxNrofUL-Allocations-r16 INTEGER ::= 64 -- Maximum number of PUSCH time domain resource allocations +maxNrofP0-PUSCH-Set-r16 INTEGER ::= 2 -- Maximum number of P0 PUSCH set(s) +maxOnDemandSIB-r16 INTEGER ::= 8 -- Maximum number of SIB(s) that can be requested on-demand +maxOnDemandPosSIB-r16 INTEGER ::= 32 -- Maximum number of posSIB(s) that can be requested on-demand +maxCI-DCI-PayloadSize-r16 INTEGER ::= 126 -- Maximum number of the DCI size for CI +maxCI-DCI-PayloadSize-r16-1 INTEGER ::= 125 -- Maximum number of the DCI size for CI minus 1 +maxWLAN-Id-Report-r16 INTEGER ::= 32 -- Maximum number of WLAN IDs to report +maxWLAN-Name-r16 INTEGER ::= 4 -- Maximum number of WLAN name +maxRAReport-r16 INTEGER ::= 8 -- Maximum number of RA procedures information to be included in the RA report +maxTxConfig-r16 INTEGER ::= 64 -- Maximum number of sidelink transmission parameters configurations +maxTxConfig-1-r16 INTEGER ::= 63 -- Maximum number of sidelink transmission parameters configurations minus 1 +maxPSSCH-TxConfig-r16 INTEGER ::= 16 -- Maximum number of PSSCH TX configurations +maxNrofCLI-RSSI-Resources-r16 INTEGER ::= 64 -- Maximum number of CLI-RSSI resources for UE +maxNrofCLI-RSSI-Resources-r16-1 INTEGER ::= 63 -- Maximum number of CLI-RSSI resources for UE minus 1 +maxNrofCLI-SRS-Resources-r16 INTEGER ::= 32 -- Maximum number of SRS resources for CLI measurement for UE +maxCLI-Report-r16 INTEGER ::= 8 +maxNrofConfiguredGrantConfig-r16 INTEGER ::= 12 -- Maximum number of configured grant configurations per BWP +maxNrofConfiguredGrantConfig-r16-1 INTEGER ::= 11 -- Maximum number of configured grant configurations per BWP minus 1 +maxNrofCG-Type2DeactivationState INTEGER ::= 16 -- Maximum number of deactivation state for type 2 configured grants per BWP +maxNrofConfiguredGrantConfigMAC-r16 INTEGER ::= 32 -- Maximum number of configured grant configurations per MAC entity +maxNrofConfiguredGrantConfigMAC-r16-1 INTEGER ::= 31 -- Maximum number of configured grant configurations per MAC entity minus 1 +maxNrofSPS-Config-r16 INTEGER ::= 8 -- Maximum number of SPS configurations per BWP +maxNrofSPS-Config-r16-1 INTEGER ::= 7 -- Maximum number of SPS configurations per BWP minus 1 +maxNrofSPS-DeactivationState INTEGER ::= 16 -- Maximum number of deactivation state for SPS per BWP +maxNrofDormancyGroups INTEGER ::= 5 -- +maxNrofPUCCH-ResourceGroups-1-r16 INTEGER ::= 3 -- +maxNrofServingCellsTCI-r16 INTEGER ::= 32 -- Maximum number of serving cells in simultaneousTCI-UpdateList + +-- TAG-MULTIPLICITY-AND-TYPE-CONSTRAINT-DEFINITIONS-STOP + +END + +-- NR-UE-VARIABLES-START + +NR-UE-Variables DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + ARFCN-ValueNR, + CellIdentity, + EUTRA-PhysCellId, + MeasId, + MeasIdToAddModList, + MeasIdleCarrierEUTRA-r16, + MeasIdleCarrierNR-r16, + MeasResultIdleEUTRA-r16, + MeasResultIdleNR-r16, + MeasObjectToAddModList, + PhysCellId, + RNTI-Value, + ReportConfigToAddModList, + RSRP-Range, + SL-MeasId-r16, + SL-MeasIdList-r16, + SL-MeasObjectList-r16, + SL-ReportConfigList-r16, + SL-QuantityConfig-r16, + Tx-PoolMeasList-r16, + QuantityConfig, + maxNrofCellMeas, + maxNrofMeasId, + maxFreqIdle-r16, + PhysCellIdUTRA-FDD-r16, + ValidityAreaList-r16, + CondReconfigToAddModList-r16, + ConnEstFailReport-r16, + LoggingDuration-r16, + LoggingInterval-r16, + LogMeasInfoList-r16, + LogMeasInfo-r16, + RA-Report-r16, + RLF-Report-r16, + TraceReference-r16, + WLAN-Identifiers-r16, + WLAN-NameList-r16, + BT-NameList-r16, + PLMN-Identity, + maxPLMN, + RA-ReportList-r16, + VisitedCellInfoList-r16, + AbsoluteTimeInfo-r16, + LoggedEventTriggerConfig-r16, + LoggedPeriodicalReportConfig-r16, + Sensor-NameList-r16, + PLMN-IdentityList2-r16, + AreaConfiguration-r16, + maxNrofSL-MeasId-r16, + maxNrofFreqSL-r16, + maxNrofCLI-RSSI-Resources-r16, + maxNrofCLI-SRS-Resources-r16, + RSSI-ResourceId-r16, + SRS-ResourceId +FROM NR-RRC-Definitions; + +-- NR-UE-VARIABLES-STOP + +-- TAG-VARCONDITIONALRECONFIG-START + +VarConditionalReconfig ::= SEQUENCE { + condReconfigList CondReconfigToAddModList-r16 OPTIONAL +} + + +-- TAG-VARCONDITIONALRECONFIG-STOP +-- TAG-VARCONNESTFAILREPORT-START + +VarConnEstFailReport-r16 ::= SEQUENCE { + connEstFailReport-r16 ConnEstFailReport-r16, + plmn-Identity-r16 PLMN-Identity +} + +-- TAG-VARCONNESTFAILREPORT-STOP +-- TAG-VARLOGMEASCONFIG-START + +VarLogMeasConfig-r16-IEs ::= SEQUENCE { + areaConfiguration-r16 AreaConfiguration-r16 OPTIONAL, + bt-NameList-r16 BT-NameList-r16 OPTIONAL, + wlan-NameList-r16 WLAN-NameList-r16 OPTIONAL, + sensor-NameList-r16 Sensor-NameList-r16 OPTIONAL, + loggingDuration-r16 LoggingDuration-r16, + reportType CHOICE { + periodical LoggedPeriodicalReportConfig-r16, + eventTriggered LoggedEventTriggerConfig-r16 + } +} +-- TAG-VARLOGMEASCONFIG-STOP +-- TAG-VARLOGMEAREPORT-START + +VarLogMeasReport-r16 ::= SEQUENCE { + absoluteTimeStamp-r16 AbsoluteTimeInfo-r16, + traceReference-r16 TraceReference-r16, + traceRecordingSessionRef-r16 OCTET STRING (SIZE (2)), + tce-Id-r16 OCTET STRING (SIZE (1)), + logMeasInfoList-r16 LogMeasInfoList-r16, + plmn-IdentityList-r16 PLMN-IdentityList2-r16 +} + +-- TAG-VARLOGMEAREPORT-STOP +-- TAG-VARMEASCONFIG-START + +VarMeasConfig ::= SEQUENCE { + -- Measurement identities + measIdList MeasIdToAddModList OPTIONAL, + -- Measurement objects + measObjectList MeasObjectToAddModList OPTIONAL, + -- Reporting configurations + reportConfigList ReportConfigToAddModList OPTIONAL, + -- Other parameters + quantityConfig QuantityConfig OPTIONAL, + + s-MeasureConfig CHOICE { + ssb-RSRP RSRP-Range, + csi-RSRP RSRP-Range + } OPTIONAL + +} + +-- TAG-VARMEASCONFIG-STOP +-- TAG-VARMEASCONFIGSL-START + +VarMeasConfigSL-r16 ::= SEQUENCE { + -- NR sidelink measurement identities + sl-MeasIdList-r16 SL-MeasIdList-r16 OPTIONAL, + -- NR sidelink measurement objects + sl-MeasObjectList-r16 SL-MeasObjectList-r16 OPTIONAL, + -- NR sidelink reporting configurations + sl-reportConfigList-r16 SL-ReportConfigList-r16 OPTIONAL, + -- Other parameters + sl-QuantityConfig-r16 SL-QuantityConfig-r16 OPTIONAL +} + +-- TAG-VARMEASCONFIGSL-STOP +-- TAG-VARMEASIDLECONFIG-START + +VarMeasIdleConfig-r16 ::= SEQUENCE { + measIdleCarrierListNR-r16 SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF MeasIdleCarrierNR-r16 OPTIONAL, + measIdleCarrierListEUTRA-r16 SEQUENCE (SIZE (1..maxFreqIdle-r16)) OF MeasIdleCarrierEUTRA-r16 OPTIONAL, + measIdleDuration-r16 ENUMERATED {sec10, sec30, sec60, sec120, sec180, sec240, sec300, spare}, + validityAreaList-r16 ValidityAreaList-r16 OPTIONAL +} + +-- TAG-VARMEASIDLECONFIG-STOP +-- TAG-VARMEASIDLEREPORT-START + +VarMeasIdleReport-r16 ::= SEQUENCE { + measReportIdleNR-r16 MeasResultIdleNR-r16 OPTIONAL, + measReportIdleEUTRA-r16 MeasResultIdleEUTRA-r16 OPTIONAL +} + +-- TAG-VARMEASIDLEREPORT-STOP +-- TAG-VARMEASREPORTLIST-START + +VarMeasReportList ::= SEQUENCE (SIZE (1..maxNrofMeasId)) OF VarMeasReport + +VarMeasReport ::= SEQUENCE { + -- List of measurement that have been triggered + measId MeasId, + cellsTriggeredList CellsTriggeredList OPTIONAL, + numberOfReportsSent INTEGER, + cli-TriggeredList-r16 CLI-TriggeredList-r16 OPTIONAL, + tx-PoolMeasToAddModListNR-r16 Tx-PoolMeasList-r16 OPTIONAL +} + +CellsTriggeredList ::= SEQUENCE (SIZE (1..maxNrofCellMeas)) OF CHOICE { + physCellId PhysCellId, + physCellIdEUTRA EUTRA-PhysCellId, + physCellIdUTRA-FDD-r16 PhysCellIdUTRA-FDD-r16 + } + +CLI-TriggeredList-r16 ::= CHOICE { + srs-RSRP-TriggeredList-r16 SRS-RSRP-TriggeredList-r16, + cli-RSSI-TriggeredList-r16 CLI-RSSI-TriggeredList-r16 + } + +SRS-RSRP-TriggeredList-r16 ::= SEQUENCE (SIZE (1.. maxNrofCLI-SRS-Resources-r16)) OF SRS-ResourceId + +CLI-RSSI-TriggeredList-r16 ::= SEQUENCE (SIZE (1.. maxNrofCLI-RSSI-Resources-r16)) OF RSSI-ResourceId-r16 + +-- TAG-VARMEASREPORTLIST-STOP +-- TAG-VARMEASREPORTLISTSL-START + +VarMeasReportListSL-r16 ::= SEQUENCE (SIZE (1..maxNrofSL-MeasId-r16)) OF VarMeasReportSL-r16 + +VarMeasReportSL-r16 ::= SEQUENCE { + -- List of NR sidelink measurement that have been triggered + sl-MeasId-r16 SL-MeasId-r16, + sl-FrequencyTriggeredList-r16 SEQUENCE (SIZE (1..maxNrofFreqSL-r16)) OF ARFCN-ValueNR OPTIONAL, + sl-NumberOfReportsSent-r16 INTEGER +} + +-- TAG-VARMEASREPORTLISTSL-STOP +-- TAG-VARMOBILITYHISTORYREPORT-START + +VarMobilityHistoryReport-r16 ::= VisitedCellInfoList-r16 + +-- TAG-VARMOBILITYHISTORYREPORT-STOP +-- TAG-VARPENDINGRNA-UPDATE-START + +VarPendingRNA-Update ::= SEQUENCE { + pendingRNA-Update BOOLEAN OPTIONAL +} + +-- TAG-VARPENDINGRNA-UPDATE-STOP +-- TAG-VARRA-REPORT-START + +VarRA-Report-r16 ::= SEQUENCE { + ra-ReportList-r16 RA-ReportList-r16, + plmn-IdentityList-r16 PLMN-IdentityList-r16 +} + +PLMN-IdentityList-r16 ::= SEQUENCE (SIZE (1..maxPLMN)) OF PLMN-Identity + +-- TAG-VARRA-REPORT-STOP +-- TAG-VARRESUMEMAC-INPUT-START + +VarResumeMAC-Input ::= SEQUENCE { + sourcePhysCellId PhysCellId, + targetCellIdentity CellIdentity, + source-c-RNTI RNTI-Value + +} + +-- TAG-VARRESUMEMAC-INPUT-STOP +-- TAG-VARRLF-REPORT-START + +VarRLF-Report-r16 ::= SEQUENCE { + rlf-Report-r16 RLF-Report-r16, + plmn-IdentityList-r16 PLMN-IdentityList-r16 +} + +-- TAG-VARRLF-REPORT-STOP +-- TAG-VARSHORTMAC-INPUT-START + +VarShortMAC-Input ::= SEQUENCE { + sourcePhysCellId PhysCellId, + targetCellIdentity CellIdentity, + source-c-RNTI RNTI-Value +} + +-- TAG-VARSHORTMAC-INPUT-STOP + +END + +-- TAG-NR-INTER-NODE-DEFINITIONS-START + +NR-InterNodeDefinitions DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + ARFCN-ValueNR, + ARFCN-ValueEUTRA, + CellIdentity, + CGI-InfoEUTRA, + CGI-InfoNR, + CSI-RS-Index, + CSI-RS-CellMobility, + DRX-Config, + EUTRA-PhysCellId, + FreqBandIndicatorNR, + GapConfig, + maxBandComb, + maxBands, + maxCellSFTD, + maxFeatureSetsPerBand, + maxFreqIDC-MRDC, + maxNrofCombIDC, + maxNrofSCells, + maxNrofServingCells, + maxNrofServingCells-1, + maxNrofServingCellsEUTRA, + maxNrofIndexesToReport, + maxSimultaneousBands, + MeasQuantityResults, + MeasResultCellListSFTD-EUTRA, + MeasResultCellListSFTD-NR, + MeasResultList2NR, + MeasResultSCG-Failure, + MeasResultServFreqListEUTRA-SCG, + NeedForGapsInfoNR-r16, + OverheatingAssistance, + P-Max, + PhysCellId, + RadioBearerConfig, + RAN-NotificationAreaInfo, + RRCReconfiguration, + ServCellIndex, + SetupRelease, + SSB-Index, + SSB-MTC, + SSB-ToMeasure, + SS-RSSI-Measurement, + ShortMAC-I, + SubcarrierSpacing, + UEAssistanceInformation, + UE-CapabilityRAT-ContainerList, + maxNrofCLI-RSSI-Resources-r16, + maxNrofCLI-SRS-Resources-r16, + RSSI-ResourceId-r16, + SidelinkUEInformationNR-r16, + SRS-ResourceId +FROM NR-RRC-Definitions; + +-- TAG-NR-INTER-NODE-DEFINITIONS-STOP + +-- TAG-HANDOVER-COMMAND-START + +HandoverCommand ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + handoverCommand HandoverCommand-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +HandoverCommand-IEs ::= SEQUENCE { + handoverCommandMessage OCTET STRING (CONTAINING RRCReconfiguration), + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-HANDOVER-COMMAND-STOP +-- TAG-HANDOVER-PREPARATION-INFORMATION-START + +HandoverPreparationInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + handoverPreparationInformation HandoverPreparationInformation-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +HandoverPreparationInformation-IEs ::= SEQUENCE { + ue-CapabilityRAT-List UE-CapabilityRAT-ContainerList, + sourceConfig AS-Config OPTIONAL, -- Cond HO + rrm-Config RRM-Config OPTIONAL, + as-Context AS-Context OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +AS-Config ::= SEQUENCE { + rrcReconfiguration OCTET STRING (CONTAINING RRCReconfiguration), + ..., + [[ + sourceRB-SN-Config OCTET STRING (CONTAINING RadioBearerConfig) OPTIONAL, + sourceSCG-NR-Config OCTET STRING (CONTAINING RRCReconfiguration) OPTIONAL, + sourceSCG-EUTRA-Config OCTET STRING OPTIONAL + ]], + [[ + sourceSCG-Configured ENUMERATED {true} OPTIONAL + ]] + +} + +AS-Context ::= SEQUENCE { + reestablishmentInfo ReestablishmentInfo OPTIONAL, + configRestrictInfo ConfigRestrictInfoSCG OPTIONAL, + ..., + [[ ran-NotificationAreaInfo RAN-NotificationAreaInfo OPTIONAL + ]], + [[ ueAssistanceInformation OCTET STRING (CONTAINING UEAssistanceInformation) OPTIONAL -- Cond HO2 + ]], + [[ + selectedBandCombinationSN BandCombinationInfoSN OPTIONAL + ]], + [[ + configRestrictInfoDAPS-r16 ConfigRestrictInfoDAPS-r16 OPTIONAL, + sidelinkUEInformationNR-r16 OCTET STRING OPTIONAL, + sidelinkUEInformationEUTRA-r16 OCTET STRING OPTIONAL, + ueAssistanceInformationEUTRA-r16 OCTET STRING OPTIONAL, + ueAssistanceInformationSCG-r16 OCTET STRING (CONTAINING UEAssistanceInformation) OPTIONAL, -- Cond HO2 + needForGapsInfoNR-r16 NeedForGapsInfoNR-r16 OPTIONAL + ]] +} + +ConfigRestrictInfoDAPS-r16 ::= SEQUENCE { + powerCoordination-r16 SEQUENCE { + p-DAPS-Source-r16 P-Max, + p-DAPS-Target-r16 P-Max, + uplinkPowerSharingDAPS-Mode-r16 ENUMERATED {semi-static-mode1, semi-static-mode2, dynamic } + } OPTIONAL +} + +ReestablishmentInfo ::= SEQUENCE { + sourcePhysCellId PhysCellId, + targetCellShortMAC-I ShortMAC-I, + additionalReestabInfoList ReestabNCellInfoList OPTIONAL +} + +ReestabNCellInfoList ::= SEQUENCE ( SIZE (1..maxCellPrep) ) OF ReestabNCellInfo + +ReestabNCellInfo::= SEQUENCE{ + cellIdentity CellIdentity, + key-gNodeB-Star BIT STRING (SIZE (256)), + shortMAC-I ShortMAC-I +} + +RRM-Config ::= SEQUENCE { + ue-InactiveTime ENUMERATED { + s1, s2, s3, s5, s7, s10, s15, s20, + s25, s30, s40, s50, min1, min1s20, min1s40, + min2, min2s30, min3, min3s30, min4, min5, min6, + min7, min8, min9, min10, min12, min14, min17, min20, + min24, min28, min33, min38, min44, min50, hr1, + hr1min30, hr2, hr2min30, hr3, hr3min30, hr4, hr5, hr6, + hr8, hr10, hr13, hr16, hr20, day1, day1hr12, day2, + day2hr12, day3, day4, day5, day7, day10, day14, day19, + day24, day30, dayMoreThan30} OPTIONAL, + candidateCellInfoList MeasResultList2NR OPTIONAL, + ..., + [[ + candidateCellInfoListSN-EUTRA MeasResultServFreqListEUTRA-SCG OPTIONAL + ]] +} + +-- TAG-HANDOVER-PREPARATION-INFORMATION-STOP +-- TAG-CG-CONFIG-START + +CG-Config ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + cg-Config CG-Config-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +CG-Config-IEs ::= SEQUENCE { + scg-CellGroupConfig OCTET STRING (CONTAINING RRCReconfiguration) OPTIONAL, + scg-RB-Config OCTET STRING (CONTAINING RadioBearerConfig) OPTIONAL, + configRestrictModReq ConfigRestrictModReqSCG OPTIONAL, + drx-InfoSCG DRX-Info OPTIONAL, + candidateCellInfoListSN OCTET STRING (CONTAINING MeasResultList2NR) OPTIONAL, + measConfigSN MeasConfigSN OPTIONAL, + selectedBandCombination BandCombinationInfoSN OPTIONAL, + fr-InfoListSCG FR-InfoList OPTIONAL, + candidateServingFreqListNR CandidateServingFreqListNR OPTIONAL, + nonCriticalExtension CG-Config-v1540-IEs OPTIONAL +} + +CG-Config-v1540-IEs ::= SEQUENCE { + pSCellFrequency ARFCN-ValueNR OPTIONAL, + reportCGI-RequestNR SEQUENCE { + requestedCellInfo SEQUENCE { + ssbFrequency ARFCN-ValueNR, + cellForWhichToReportCGI PhysCellId + } OPTIONAL + } OPTIONAL, + ph-InfoSCG PH-TypeListSCG OPTIONAL, + nonCriticalExtension CG-Config-v1560-IEs OPTIONAL +} + +CG-Config-v1560-IEs ::= SEQUENCE { + pSCellFrequencyEUTRA ARFCN-ValueEUTRA OPTIONAL, + scg-CellGroupConfigEUTRA OCTET STRING OPTIONAL, + candidateCellInfoListSN-EUTRA OCTET STRING OPTIONAL, + candidateServingFreqListEUTRA CandidateServingFreqListEUTRA OPTIONAL, + needForGaps ENUMERATED {true} OPTIONAL, + drx-ConfigSCG DRX-Config OPTIONAL, + reportCGI-RequestEUTRA SEQUENCE { + requestedCellInfoEUTRA SEQUENCE { + eutraFrequency ARFCN-ValueEUTRA, + cellForWhichToReportCGI-EUTRA EUTRA-PhysCellId + } OPTIONAL + } OPTIONAL, + nonCriticalExtension CG-Config-v1590-IEs OPTIONAL +} + +CG-Config-v1590-IEs ::= SEQUENCE { + scellFrequenciesSN-NR SEQUENCE (SIZE (1.. maxNrofServingCells-1)) OF ARFCN-ValueNR OPTIONAL, + scellFrequenciesSN-EUTRA SEQUENCE (SIZE (1.. maxNrofServingCells-1)) OF ARFCN-ValueEUTRA OPTIONAL, + nonCriticalExtension CG-Config-v1610-IEs OPTIONAL +} + +CG-Config-v1610-IEs ::= SEQUENCE { + drx-InfoSCG2 DRX-Info2 OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +PH-TypeListSCG ::= SEQUENCE (SIZE (1..maxNrofServingCells)) OF PH-InfoSCG + +PH-InfoSCG ::= SEQUENCE { + servCellIndex ServCellIndex, + ph-Uplink PH-UplinkCarrierSCG, + ph-SupplementaryUplink PH-UplinkCarrierSCG OPTIONAL, + ... +} + +PH-UplinkCarrierSCG ::= SEQUENCE{ + ph-Type1or3 ENUMERATED {type1, type3}, + ... +} + +MeasConfigSN ::= SEQUENCE { + measuredFrequenciesSN SEQUENCE (SIZE (1..maxMeasFreqsSN)) OF NR-FreqInfo OPTIONAL, + ... +} + +NR-FreqInfo ::= SEQUENCE { + measuredFrequency ARFCN-ValueNR OPTIONAL, + ... +} + +ConfigRestrictModReqSCG ::= SEQUENCE { + requestedBC-MRDC BandCombinationInfoSN OPTIONAL, + requestedP-MaxFR1 P-Max OPTIONAL, + ..., + [[ + requestedPDCCH-BlindDetectionSCG INTEGER (1..15) OPTIONAL, + requestedP-MaxEUTRA P-Max OPTIONAL + ]], + [[ + requestedP-MaxFR2-r16 P-Max OPTIONAL, + requestedMaxInterFreqMeasIdSCG-r16 INTEGER(1..maxMeasIdentitiesMN) OPTIONAL, + requestedMaxIntraFreqMeasIdSCG-r16 INTEGER(1..maxMeasIdentitiesMN) OPTIONAL + ]] +} + +BandCombinationIndex ::= INTEGER (1..maxBandComb) + +BandCombinationInfoSN ::= SEQUENCE { + bandCombinationIndex BandCombinationIndex, + requestedFeatureSets FeatureSetEntryIndex +} + +FR-InfoList ::= SEQUENCE (SIZE (1..maxNrofServingCells-1)) OF FR-Info + +FR-Info ::= SEQUENCE { + servCellIndex ServCellIndex, + fr-Type ENUMERATED {fr1, fr2} +} + +CandidateServingFreqListNR ::= SEQUENCE (SIZE (1.. maxFreqIDC-MRDC)) OF ARFCN-ValueNR + +CandidateServingFreqListEUTRA ::= SEQUENCE (SIZE (1.. maxFreqIDC-MRDC)) OF ARFCN-ValueEUTRA + +-- TAG-CG-CONFIG-STOP +-- TAG-CG-CONFIG-INFO-START + +CG-ConfigInfo ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + cg-ConfigInfo CG-ConfigInfo-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +CG-ConfigInfo-IEs ::= SEQUENCE { + ue-CapabilityInfo OCTET STRING (CONTAINING UE-CapabilityRAT-ContainerList) OPTIONAL,-- Cond SN-AddMod + candidateCellInfoListMN MeasResultList2NR OPTIONAL, + candidateCellInfoListSN OCTET STRING (CONTAINING MeasResultList2NR) OPTIONAL, + measResultCellListSFTD-NR MeasResultCellListSFTD-NR OPTIONAL, + scgFailureInfo SEQUENCE { + failureType ENUMERATED { t310-Expiry, randomAccessProblem, + rlc-MaxNumRetx, synchReconfigFailure-SCG, + scg-reconfigFailure, + srb3-IntegrityFailure}, + measResultSCG OCTET STRING (CONTAINING MeasResultSCG-Failure) + } OPTIONAL, + configRestrictInfo ConfigRestrictInfoSCG OPTIONAL, + drx-InfoMCG DRX-Info OPTIONAL, + measConfigMN MeasConfigMN OPTIONAL, + sourceConfigSCG OCTET STRING (CONTAINING RRCReconfiguration) OPTIONAL, + scg-RB-Config OCTET STRING (CONTAINING RadioBearerConfig) OPTIONAL, + mcg-RB-Config OCTET STRING (CONTAINING RadioBearerConfig) OPTIONAL, + mrdc-AssistanceInfo MRDC-AssistanceInfo OPTIONAL, + nonCriticalExtension CG-ConfigInfo-v1540-IEs OPTIONAL +} + +CG-ConfigInfo-v1540-IEs ::= SEQUENCE { + ph-InfoMCG PH-TypeListMCG OPTIONAL, + measResultReportCGI SEQUENCE { + ssbFrequency ARFCN-ValueNR, + cellForWhichToReportCGI PhysCellId, + cgi-Info CGI-InfoNR + } OPTIONAL, + nonCriticalExtension CG-ConfigInfo-v1560-IEs OPTIONAL +} + +CG-ConfigInfo-v1560-IEs ::= SEQUENCE { + candidateCellInfoListMN-EUTRA OCTET STRING OPTIONAL, + candidateCellInfoListSN-EUTRA OCTET STRING OPTIONAL, + sourceConfigSCG-EUTRA OCTET STRING OPTIONAL, + scgFailureInfoEUTRA SEQUENCE { + failureTypeEUTRA ENUMERATED { t313-Expiry, randomAccessProblem, + rlc-MaxNumRetx, scg-ChangeFailure}, + measResultSCG-EUTRA OCTET STRING + } OPTIONAL, + drx-ConfigMCG DRX-Config OPTIONAL, + measResultReportCGI-EUTRA SEQUENCE { + eutraFrequency ARFCN-ValueEUTRA, + cellForWhichToReportCGI-EUTRA EUTRA-PhysCellId, + cgi-InfoEUTRA CGI-InfoEUTRA + } OPTIONAL, + measResultCellListSFTD-EUTRA MeasResultCellListSFTD-EUTRA OPTIONAL, + fr-InfoListMCG FR-InfoList OPTIONAL, + nonCriticalExtension CG-ConfigInfo-v1570-IEs OPTIONAL +} + +CG-ConfigInfo-v1570-IEs ::= SEQUENCE { + sftdFrequencyList-NR SFTD-FrequencyList-NR OPTIONAL, + sftdFrequencyList-EUTRA SFTD-FrequencyList-EUTRA OPTIONAL, + nonCriticalExtension CG-ConfigInfo-v1590-IEs OPTIONAL +} + +CG-ConfigInfo-v1590-IEs ::= SEQUENCE { + servFrequenciesMN-NR SEQUENCE (SIZE (1.. maxNrofServingCells-1)) OF ARFCN-ValueNR OPTIONAL, + nonCriticalExtension CG-ConfigInfo-v1610-IEs OPTIONAL +} + +CG-ConfigInfo-v1610-IEs ::= SEQUENCE { + drx-InfoMCG2 DRX-Info2 OPTIONAL, + alignedDRX-Indication ENUMERATED {true} OPTIONAL, + scgFailureInfo-r16 SEQUENCE { + failureType-r16 ENUMERATED { scg-lbtFailure-r16, beamFailureRecoveryFailure-r16, + t312-Expiry-r16, bh-RLF-r16, + spare4, spare3, spare2, spare1}, + measResultSCG-r16 OCTET STRING (CONTAINING MeasResultSCG-Failure) + } OPTIONAL, + scgFailureInfoEUTRA-r16 SEQUENCE { + failureTypeEUTRA-r16 ENUMERATED { scg-lbtFailure-r16, beamFailureRecoveryFailure-r16, + t312-Expiry-r16, bh-RLF-r16, + spare4, spare3, spare2, spare1}, + measResultSCG-EUTRA-r16 OCTET STRING + } OPTIONAL, + sidelinkUEInformationNR-r16 OCTET STRING (CONTAINING SidelinkUEInformationNR-r16) OPTIONAL, + sidelinkUEInformationEUTRA-r16 OCTET STRING OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} +SFTD-FrequencyList-NR ::= SEQUENCE (SIZE (1..maxCellSFTD)) OF ARFCN-ValueNR + +SFTD-FrequencyList-EUTRA ::= SEQUENCE (SIZE (1..maxCellSFTD)) OF ARFCN-ValueEUTRA + +ConfigRestrictInfoSCG ::= SEQUENCE { + allowedBC-ListMRDC BandCombinationInfoList OPTIONAL, + powerCoordination-FR1 SEQUENCE { + p-maxNR-FR1 P-Max OPTIONAL, + p-maxEUTRA P-Max OPTIONAL, + p-maxUE-FR1 P-Max OPTIONAL + } OPTIONAL, + servCellIndexRangeSCG SEQUENCE { + lowBound ServCellIndex, + upBound ServCellIndex + } OPTIONAL, -- Cond SN-AddMod + maxMeasFreqsSCG INTEGER(1..maxMeasFreqsMN) OPTIONAL, + dummy INTEGER(1..maxMeasIdentitiesMN) OPTIONAL, + ..., + [[ + selectedBandEntriesMNList SEQUENCE (SIZE (1..maxBandComb)) OF SelectedBandEntriesMN OPTIONAL, + pdcch-BlindDetectionSCG INTEGER (1..15) OPTIONAL, + maxNumberROHC-ContextSessionsSN INTEGER(0.. 16384) OPTIONAL + ]], + [[ + maxIntraFreqMeasIdentitiesSCG INTEGER(1..maxMeasIdentitiesMN) OPTIONAL, + maxInterFreqMeasIdentitiesSCG INTEGER(1..maxMeasIdentitiesMN) OPTIONAL + ]], + [[ + p-maxNR-FR1-MCG-r16 P-Max OPTIONAL, + powerCoordination-FR2-r16 SEQUENCE { + p-maxNR-FR2-MCG-r16 P-Max OPTIONAL, + p-maxNR-FR2-SCG-r16 P-Max OPTIONAL, + p-maxUE-FR2-r16 P-Max OPTIONAL + } OPTIONAL, + nrdc-PC-mode-FR1-r16 ENUMERATED {semi-static-mode1, semi-static-mode2, dynamic} OPTIONAL, + nrdc-PC-mode-FR2-r16 ENUMERATED {semi-static-mode1, semi-static-mode2, dynamic} OPTIONAL, + maxMeasSRS-ResourceSCG-r16 INTEGER(0..maxNrofCLI-SRS-Resources-r16) OPTIONAL, + maxMeasCLI-ResourceSCG-r16 INTEGER(0..maxNrofCLI-RSSI-Resources-r16) OPTIONAL, + maxNumberEHC-ContextsSN-r16 INTEGER(0..65536) OPTIONAL, + allowedReducedConfigForOverheating-r16 OverheatingAssistance OPTIONAL + ]] +} + +SelectedBandEntriesMN ::= SEQUENCE (SIZE (1..maxSimultaneousBands)) OF BandEntryIndex + +BandEntryIndex ::= INTEGER (0.. maxNrofServingCells) + +PH-TypeListMCG ::= SEQUENCE (SIZE (1..maxNrofServingCells)) OF PH-InfoMCG + +PH-InfoMCG ::= SEQUENCE { + servCellIndex ServCellIndex, + ph-Uplink PH-UplinkCarrierMCG, + ph-SupplementaryUplink PH-UplinkCarrierMCG OPTIONAL, + ... +} + +PH-UplinkCarrierMCG ::= SEQUENCE{ + ph-Type1or3 ENUMERATED {type1, type3}, + ... +} + +BandCombinationInfoList ::= SEQUENCE (SIZE (1..maxBandComb)) OF BandCombinationInfo + +BandCombinationInfo ::= SEQUENCE { + bandCombinationIndex BandCombinationIndex, + allowedFeatureSetsList SEQUENCE (SIZE (1..maxFeatureSetsPerBand)) OF FeatureSetEntryIndex +} + +FeatureSetEntryIndex ::= INTEGER (1.. maxFeatureSetsPerBand) + +DRX-Info ::= SEQUENCE { + drx-LongCycleStartOffset CHOICE { + ms10 INTEGER(0..9), + ms20 INTEGER(0..19), + ms32 INTEGER(0..31), + ms40 INTEGER(0..39), + ms60 INTEGER(0..59), + ms64 INTEGER(0..63), + ms70 INTEGER(0..69), + ms80 INTEGER(0..79), + ms128 INTEGER(0..127), + ms160 INTEGER(0..159), + ms256 INTEGER(0..255), + ms320 INTEGER(0..319), + ms512 INTEGER(0..511), + ms640 INTEGER(0..639), + ms1024 INTEGER(0..1023), + ms1280 INTEGER(0..1279), + ms2048 INTEGER(0..2047), + ms2560 INTEGER(0..2559), + ms5120 INTEGER(0..5119), + ms10240 INTEGER(0..10239) + }, + shortDRX SEQUENCE { + drx-ShortCycle ENUMERATED { + ms2, ms3, ms4, ms5, ms6, ms7, ms8, ms10, ms14, ms16, ms20, ms30, ms32, + ms35, ms40, ms64, ms80, ms128, ms160, ms256, ms320, ms512, ms640, spare9, + spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 }, + drx-ShortCycleTimer INTEGER (1..16) + } OPTIONAL +} + +DRX-Info2 ::= SEQUENCE { + drx-onDurationTimer CHOICE { + subMilliSeconds INTEGER (1..31), + milliSeconds ENUMERATED { + ms1, ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, ms40, ms50, ms60, + ms80, ms100, ms200, ms300, ms400, ms500, ms600, ms800, ms1000, ms1200, + ms1600, spare8, spare7, spare6, spare5, spare4, spare3, spare2, spare1 } + } +} + +MeasConfigMN ::= SEQUENCE { + measuredFrequenciesMN SEQUENCE (SIZE (1..maxMeasFreqsMN)) OF NR-FreqInfo OPTIONAL, + measGapConfig SetupRelease { GapConfig } OPTIONAL, + gapPurpose ENUMERATED {perUE, perFR1} OPTIONAL, + ..., + [[ measGapConfigFR2 SetupRelease { GapConfig } OPTIONAL + ]] + +} + +MRDC-AssistanceInfo ::= SEQUENCE { + affectedCarrierFreqCombInfoListMRDC SEQUENCE (SIZE (1..maxNrofCombIDC)) OF AffectedCarrierFreqCombInfoMRDC, + ..., + [[ + overheatingAssistanceSCG-r16 OCTET STRING (CONTAINING OverheatingAssistance) OPTIONAL + ]] +} + +AffectedCarrierFreqCombInfoMRDC ::= SEQUENCE { + victimSystemType VictimSystemType, + interferenceDirectionMRDC ENUMERATED {eutra-nr, nr, other, utra-nr-other, nr-other, spare3, spare2, spare1}, + affectedCarrierFreqCombMRDC SEQUENCE { + affectedCarrierFreqCombEUTRA AffectedCarrierFreqCombEUTRA OPTIONAL, + affectedCarrierFreqCombNR AffectedCarrierFreqCombNR + } OPTIONAL +} + +VictimSystemType ::= SEQUENCE { + gps ENUMERATED {true} OPTIONAL, + glonass ENUMERATED {true} OPTIONAL, + bds ENUMERATED {true} OPTIONAL, + galileo ENUMERATED {true} OPTIONAL, + wlan ENUMERATED {true} OPTIONAL, + bluetooth ENUMERATED {true} OPTIONAL +} + +AffectedCarrierFreqCombEUTRA ::= SEQUENCE (SIZE (1..maxNrofServingCellsEUTRA)) OF ARFCN-ValueEUTRA + +AffectedCarrierFreqCombNR ::= SEQUENCE (SIZE (1..maxNrofServingCells)) OF ARFCN-ValueNR + +-- TAG-CG-CONFIG-INFO-STOP +-- TAG-MEASUREMENT-TIMING-CONFIGURATION-START + +MeasurementTimingConfiguration ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + measTimingConf MeasurementTimingConfiguration-IEs, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +MeasurementTimingConfiguration-IEs ::= SEQUENCE { + measTiming MeasTimingList OPTIONAL, + nonCriticalExtension MeasurementTimingConfiguration-v1550-IEs OPTIONAL +} + +MeasurementTimingConfiguration-v1550-IEs ::= SEQUENCE { + campOnFirstSSB BOOLEAN, + psCellOnlyOnFirstSSB BOOLEAN, + nonCriticalExtension MeasurementTimingConfiguration-v1610-IEs OPTIONAL +} + +MeasurementTimingConfiguration-v1610-IEs ::= SEQUENCE { + csi-RS-Config-r16 SEQUENCE { + csi-RS-SubcarrierSpacing-r16 SubcarrierSpacing, + csi-RS-CellMobility-r16 CSI-RS-CellMobility, + refSSBFreq-r16 ARFCN-ValueNR + }, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +MeasTimingList ::= SEQUENCE (SIZE (1..maxMeasFreqsMN)) OF MeasTiming + +MeasTiming ::= SEQUENCE { + frequencyAndTiming SEQUENCE { + carrierFreq ARFCN-ValueNR, + ssbSubcarrierSpacing SubcarrierSpacing, + ssb-MeasurementTimingConfiguration SSB-MTC, + ss-RSSI-Measurement SS-RSSI-Measurement OPTIONAL + } OPTIONAL, +..., + [[ + ssb-ToMeasure SSB-ToMeasure OPTIONAL, + physCellId PhysCellId OPTIONAL + ]] +} + +-- TAG-MEASUREMENT-TIMING-CONFIGURATION-STOP +-- TAG-UE-RADIO-PAGING-INFORMATION-START + +UERadioPagingInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + ueRadioPagingInformation UERadioPagingInformation-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UERadioPagingInformation-IEs ::= SEQUENCE { + supportedBandListNRForPaging SEQUENCE (SIZE (1..maxBands)) OF FreqBandIndicatorNR OPTIONAL, + nonCriticalExtension SEQUENCE {} OPTIONAL +} + + +-- TAG-UE-RADIO-PAGING-INFORMATION-STOP +-- TAG-UE-RADIO-ACCESS-CAPABILITY-INFORMATION-START + +UERadioAccessCapabilityInformation ::= SEQUENCE { + criticalExtensions CHOICE { + c1 CHOICE{ + ueRadioAccessCapabilityInformation UERadioAccessCapabilityInformation-IEs, + spare7 NULL, + spare6 NULL, spare5 NULL, spare4 NULL, + spare3 NULL, spare2 NULL, spare1 NULL + }, + criticalExtensionsFuture SEQUENCE {} + } +} + +UERadioAccessCapabilityInformation-IEs ::= SEQUENCE { + ue-RadioAccessCapabilityInfo OCTET STRING (CONTAINING UE-CapabilityRAT-ContainerList), + nonCriticalExtension SEQUENCE {} OPTIONAL +} + +-- TAG-UE-RADIO-ACCESS-CAPABILITY-INFORMATION-STOP +-- TAG-NR-MULTIPLICITY-AND-CONSTRAINTS-START + +maxMeasFreqsMN INTEGER ::= 32 -- Maximum number of MN-configured measurement frequencies +maxMeasFreqsSN INTEGER ::= 32 -- Maximum number of SN-configured measurement frequencies +maxMeasIdentitiesMN INTEGER ::= 62 -- Maximum number of measurement identities that a UE can be configured with +maxCellPrep INTEGER ::= 32 -- Maximum number of cells prepared for handover + +-- TAG-NR-MULTIPLICITY-AND-CONSTRAINTS-STOP + +-- TAG-NR-INTER-NODE-DEFINITIONS-END-START + +END + +-- TAG-NR-INTER-NODE-DEFINITIONS-END-STOP diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 9a53a5bbe0..c53d44983c 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -54,6 +54,7 @@ #include "NR_BCCH-BCH-Message.h" #include "NR_PLMN-IdentityInfo.h" #include "NR_MCC-MNC-Digit.h" +#include "NR_NG-5G-S-TMSI.h" //#include "MCCH-Message.h" //#include "MBSFNAreaConfiguration-r9.h" //#include "SCellToAddMod-r10.h" @@ -89,10 +90,10 @@ typedef struct nr_uid_linear_allocator_s { #define PROTOCOL_NR_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT -#define PROTOCOL_NR_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) +#define PROTOCOL_NR_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_NR_CTXT_ARGS(CTXT_Pp) #define PROTOCOL_NR_RRC_CTXT_FMT PROTOCOL_CTXT_FMT -#define PROTOCOL_NR_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) +#define PROTOCOL_NR_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_NR_CTXT_ARGS(CTXT_Pp) #define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! @@ -149,7 +150,7 @@ typedef struct UE_RRC_INFO_NR_s { uint32_t SIStatus; uint32_t SIcnt; uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA - uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 + uint16_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 uint8_t handoverTarget; //HO_STATE_t ho_state; uint16_t @@ -168,8 +169,9 @@ typedef struct UE_RRC_INFO_NR_s { typedef struct UE_S_TMSI_NR_s { boolean_t presence; - mme_code_t mme_code; - m_tmsi_t m_tmsi; + uint16_t amf_set_id; + uint8_t amf_pointer; + uint32_t fiveg_tmsi; } __attribute__ ((__packed__)) NR_UE_S_TMSI; @@ -246,6 +248,32 @@ typedef struct SRB_INFO_TABLE_ENTRY_NR_s { uint32_t Next_check_frame; } NR_SRB_INFO_TABLE_ENTRY; +typedef struct nr_rrc_guami_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_len; + uint8_t amf_region_id; + uint16_t amf_set_id; + uint8_t amf_pointer; +} nr_rrc_guami_t; + +typedef enum pdu_session_satus_e { + PDU_SESSION_STATUS_NEW, + PDU_SESSION_STATUS_DONE, + PDU_SESSION_STATUS_ESTABLISHED, + PDU_SESSION_STATUS_REESTABLISHED, // after HO + PDU_SESSION_STATUS_TOMODIFY, // ENDC NSA + PDU_SESSION_STATUS_FAILED, + PDU_SESSION_STATUS_TORELEASE // to release DRB between eNB and UE +} pdu_session_status_t; + +typedef struct pdu_session_param_s { + pdusession_t param; + uint8_t status; + uint8_t xid; // transaction_id + ngap_Cause_t cause; + uint8_t cause_value; +} __attribute__ ((__packed__)) pdu_session_param_t; typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; @@ -267,7 +295,9 @@ typedef struct gNB_RRC_UE_s { NR_UE_NR_Capability_t* UE_Capability_nr; + int UE_Capability_size; NR_UE_MRDC_Capability_t* UE_Capability_MRDC; + int UE_MRDC_Capability_size; NR_CellGroupConfig_t *secondaryCellGroup; NR_RRCReconfiguration_t *reconfig; @@ -275,13 +305,12 @@ typedef struct gNB_RRC_UE_s { ImsiMobileIdentity_t imsi; -#if defined(ENABLE_SECURITY) - /* KeNB as derived from KASME received from EPC */ - uint8_t kenb[32]; - int8_t kenb_ncc; + /* KgNB as derived from KASME received from EPC */ + uint8_t kgnb[32]; + int8_t kgnb_ncc; uint8_t nh[32]; int8_t nh_ncc; -#endif + /* Used integrity/ciphering algorithms */ NR_CipheringAlgorithm_t ciphering_algorithm; e_NR_IntegrityProtAlgorithm integrity_algorithm; @@ -290,49 +319,68 @@ typedef struct gNB_RRC_UE_s { rnti_t rnti; uint64_t random_ue_identity; - /* Information from UE RRC ConnectionRequest */ - UE_S_TMSI Initialue_identity_s_TMSI; + /* Information from UE RRC Setup Request */ + NR_UE_S_TMSI Initialue_identity_5g_s_TMSI; + uint64_t ng_5G_S_TMSI_Part1; + uint16_t ng_5G_S_TMSI_Part2; NR_EstablishmentCause_t establishment_cause; /* Information from UE RRC ConnectionReestablishmentRequest */ - NR_ReestablishmentCause_t reestablishment_cause; + NR_ReestablishmentCause_t reestablishment_cause; /* UE id for initial connection to S1AP */ uint16_t ue_initial_id; /* Information from S1AP initial_context_setup_req */ uint32_t gNB_ue_s1ap_id :24; + uint32_t gNB_ue_ngap_id; + uint64_t amf_ue_ngap_id:40; + nr_rrc_guami_t ue_guami; - security_capabilities_t security_capabilities; + ngap_security_capabilities_t security_capabilities; /* Total number of e_rab already setup in the list */ uint8_t setup_e_rabs; /* Number of e_rab to be setup in the list */ uint8_t nb_of_e_rabs; + /* Total number of pdu session already setup in the list */ + uint8_t setup_pdu_sessions; + /* Number of pdu session to be setup in the list */ + uint8_t nb_of_pdusessions; /* Number of e_rab to be modified in the list */ uint8_t nb_of_modify_e_rabs; uint8_t nb_of_failed_e_rabs; e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ + /* list of pdu session to be setup by RRC layers */ e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; + pdu_session_param_t pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION]; //release e_rabs uint8_t nb_release_of_e_rabs; e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB]; + uint8_t nb_release_of_pdusessions; + pdusession_failed_t pdusessions_release_failed[NGAP_MAX_PDUSESSION]; // LG: For GTPV1 TUNNELS uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB]; transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB]; + rb_id_t gnb_gtp_psi[S1AP_MAX_E_RAB]; uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; uint32_t ue_release_timer_s1; uint32_t ue_release_timer_thres_s1; + uint32_t ue_release_timer_ng; + uint32_t ue_release_timer_thres_ng; uint32_t ue_release_timer_rrc; uint32_t ue_release_timer_thres_rrc; uint32_t ue_reestablishment_timer; uint32_t ue_reestablishment_timer_thres; uint8_t e_rab_release_command_flag; + uint8_t pdu_session_release_command_flag; + uint32_t ue_rrc_inactivity_timer; + int8_t reestablishment_xid; //------------------------------------------------------------------------------// NR_CellGroupId_t cellGroupId; struct NR_SpCellConfig *spCellConfig; @@ -343,6 +391,10 @@ typedef struct gNB_RRC_UE_s { struct NR_MAC_CellGroupConfig *mac_CellGroupConfig; struct NR_PhysicalCellGroupConfig *physicalCellGroupConfig; + /* Nas Pdu */ + uint8_t nas_pdu_flag; + ngap_nas_pdu_t nas_pdu; + } gNB_RRC_UE_t; typedef uid_t ue_uid_t; @@ -383,10 +435,13 @@ typedef struct { int pucch_TargetSNRx10; NR_BCCH_DL_SCH_Message_t *siblock1; NR_ServingCellConfigCommon_t *servingcellconfigcommon; + NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1; NR_CellGroupConfig_t *secondaryCellGroup[MAX_NR_RRC_UE_CONTEXTS]; NR_SRB_INFO SI; NR_SRB_INFO Srb0; int initial_csi_index[MAX_NR_RRC_UE_CONTEXTS]; + int physCellId; + int p_gNB; } rrc_gNB_carrier_data_t; //--------------------------------------------------- @@ -404,6 +459,8 @@ typedef struct gNB_RRC_INST_s { int Nb_ue; hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t + hash_table_t *initial_id2_ngap_ids; + hash_table_t *ngap_id2_ngap_ids ; // other PLMN parameters /// Mobile country code @@ -424,7 +481,6 @@ typedef struct gNB_RRC_INST_s { } gNB_RRC_INST; - #include "nr_rrc_proto.h" //should be put here otherwise compilation error #endif diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 3a6bbfd5a3..9b7d734e2c 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -65,12 +65,18 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP); -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t * cg_config_info); +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t * cg_config_info); void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti); +void fill_default_initialDownlinkBWP(NR_BWP_Downlink_t *bwp, NR_ServingCellConfigCommon_t *servingcellconfigcommon); + +void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellConfigCommon_t *servingcellconfigcommon); + +void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0); + void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CellGroupConfig_t *secondaryCellGroup, int scg_id, @@ -93,7 +99,28 @@ int generate_CG_Config(gNB_RRC_INST *rrc, int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); +void +rrc_gNB_generate_SecurityModeCommand( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +); +uint8_t +rrc_gNB_get_next_transaction_identifier( + module_id_t gnb_mod_idP +); + +void +rrc_gNB_generate_UECapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +); + +void +rrc_gNB_generate_RRCRelease( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +); /**\brief RRC eNB task. \param void *args_p Pointer on arguments to start the task. */ @@ -101,3 +128,34 @@ void *rrc_gnb_task(void *args_p); /* Trigger RRC periodic processing. To be called once per ms. */ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe); + +/**\ Function to set or overwrite PTRS DL RRC parameters. + \ *bwp Pointer to dedicated RC config structure + \ *ptrsNrb Pointer to K_ptrs N_RB related parameters + \ *ptrsMcs Pointer to L_ptrs MCS related parameters + \ *epre_Ratio Pointer to ep_ratio + \ *reOffset Pointer to RE Offset Value */ +void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset); + +uint8_t +nr_rrc_data_req( + const protocol_ctxt_t *const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_size, + uint8_t *const buffer_pP, + const pdcp_transmission_mode_t modeP +); + +int +nr_rrc_mac_remove_ue(module_id_t mod_idP, + rnti_t rntiP); + +void +rrc_gNB_generate_dedicatedRRCReconfiguration_release( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t xid, + uint32_t nas_length, + uint8_t *nas_buffer); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c old mode 100644 new mode 100755 index d94b340a92..abf85a805b --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -51,6 +51,10 @@ #include "NR_MeasResults.h" #include "LTE_UECapabilityInformation.h" #include "LTE_UL-DCCH-Message.h" +#include "NR_UL-CCCH-Message.h" +#include "NR_RRCSetupRequest-IEs.h" +#include "NR_RRCSetupComplete-IEs.h" +#include "NR_RRCReestablishmentRequest-IEs.h" #include "rlc.h" #include "rrc_eNB_UE_context.h" @@ -65,14 +69,14 @@ #include "OCG.h" #include "OCG_extern.h" -#if defined(ENABLE_SECURITY) - #include "UTIL/OSA/osa_defs.h" -#endif +#include "UTIL/OSA/osa_defs.h" #include "rrc_eNB_S1AP.h" +#include "rrc_gNB_NGAP.h" + #include "rrc_eNB_GTPV1U.h" - +#include "nr_pdcp/nr_pdcp_entity.h" #include "pdcp.h" #include "gtpv1u_eNB_task.h" @@ -82,14 +86,41 @@ #include "executables/softmodem-common.h" #include -#include "x2ap_eNB.h" +#include + +#include "BIT_STRING.h" +#include "assertions.h" //#define XER_PRINT - extern RAN_CONTEXT_t RC; +extern boolean_t nr_rrc_pdcp_config_asn1_req( + const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 + #endif + ,rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + +extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const NR_SRB_ToAddModList_t * const srb2add_listP, + const NR_DRB_ToAddModList_t * const drb2add_listP, + const NR_DRB_ToReleaseList_t * const drb2release_listP, + const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + +static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn); + mui_t rrc_gNB_mui = 0; +uint8_t first_rrcreconfiguration = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// @@ -179,10 +210,15 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -static void init_NR_SI(gNB_RRC_INST *rrc) { +static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration) { LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); rrc->carrier.MIB = (uint8_t *) malloc16(4); rrc->carrier.sizeof_MIB = do_MIB_NR(rrc,0); + + if(get_softmodem_params()->sa) { + rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration); + } + LOG_I(NR_RRC,"Done init_NR_SI\n"); rrc_mac_config_req_gNB(rrc->module_id, rrc->carrier.ssb_SubcarrierOffset, @@ -195,7 +231,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { (NR_CellGroupConfig_t *)NULL ); - if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { + if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa > 0) { // This is for phytest only, emulate first X2 message if uecap.raw file is present FILE *fd; fd = fopen("uecap.raw","r"); @@ -265,6 +301,8 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu RB_INIT(&rrc->rrc_ue_head); rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); rrc->s1ap_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); + rrc->initial_id2_ngap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); + rrc->ngap_id2_ngap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); rrc->carrier.servingcellconfigcommon = configuration->scc; rrc->carrier.ssb_SubcarrierOffset = configuration->ssb_SubcarrierOffset; rrc->carrier.pdsch_AntennaPorts = configuration->pdsch_AntennaPorts; @@ -272,7 +310,7 @@ char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigu rrc->carrier.pucch_TargetSNRx10 = configuration->pucch_TargetSNRx10; /// System Information INIT LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Checking release \n",PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt)); - init_NR_SI(rrc); + init_NR_SI(rrc, configuration); rrc_init_nr_global_param(); openair_nr_rrc_on(&ctxt); return 0; @@ -302,6 +340,1910 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x parse_CG_ConfigInfo(rrc,cg_configinfo,m); } + +//----------------------------------------------------------------------------- +uint8_t +rrc_gNB_get_next_transaction_identifier( + module_id_t gnb_mod_idP +) +//----------------------------------------------------------------------------- +{ + static uint8_t nr_rrc_transaction_identifier[NUMBER_OF_gNB_MAX]; + nr_rrc_transaction_identifier[gnb_mod_idP] = (nr_rrc_transaction_identifier[gnb_mod_idP] + 1) % NR_RRC_TRANSACTION_IDENTIFIER_NUMBER; + LOG_T(NR_RRC, "generated xid is %d\n", nr_rrc_transaction_identifier[gnb_mod_idP]); + return nr_rrc_transaction_identifier[gnb_mod_idP]; +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_RRCSetup( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const int CC_id +) +//----------------------------------------------------------------------------- +{ + LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup \n"); + NR_SRB_ToAddModList_t **SRB_configList = NULL; + + // T(T_GNB_RRC_SETUP, + // T_INT(ctxt_pP->module_id), + // T_INT(ctxt_pP->frame), + // T_INT(ctxt_pP->subframe), + // T_INT(ctxt_pP->rnti)); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + SRB_configList = &ue_p->SRB_configList; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP, + ue_context_pP, + CC_id, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + SRB_configList); + + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRC Setup\n"); + + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + // rrc_mac_config_req_eNB + + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + ue_p->Srb0.Tx_buffer.Header, // LG WARNING + ue_p->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" RRCSetup UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_p->Srb0.Tx_buffer.payload_size); + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; + /* init timers */ + // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, + ue_p->Srb0.Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); + GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#endif +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( + const protocol_ctxt_t *const ctxt_pP, + const int CC_id +) +//----------------------------------------------------------------------------- +{ + LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); + NR_SRB_ToAddModList_t **SRB_configList = NULL; + rrc_gNB_ue_context_t *ue_context_pP = NULL; + gNB_RRC_INST *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id]; + + ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0); + + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + SRB_configList = &ue_p->SRB_configList; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ctxt_pP, + ue_context_pP, + CC_id, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + SRB_configList); + + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRC Setup\n"); + + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + rrc_mac_config_req_gNB(rrc_instance_p->module_id, + rrc_instance_p->carrier.ssb_SubcarrierOffset, + rrc_instance_p->carrier.pdsch_AntennaPorts, + rrc_instance_p->carrier.pusch_TargetSNRx10, + rrc_instance_p->carrier.pucch_TargetSNRx10, + (NR_ServingCellConfigCommon_t *)rrc_instance_p->carrier.servingcellconfigcommon, + 0, + ue_context_pP->ue_context.rnti, + (NR_CellGroupConfig_t *)NULL + ); + + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + ue_p->Srb0.Tx_buffer.Header, // LG WARNING + ue_p->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" RRCSetup UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_p->Srb0.Tx_buffer.payload_size); + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; + /* init timers */ + // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, + ue_p->Srb0.Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); + GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#endif +} + +void +rrc_gNB_generate_RRCReject( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const int CC_id +) +//----------------------------------------------------------------------------- +{ + LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCReject(ctxt_pP->module_id, + (uint8_t *)ue_p->Srb0.Tx_buffer.Payload); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, + (char *)(ue_p->Srb0.Tx_buffer.Payload), + ue_p->Srb0.Tx_buffer.payload_size, + "[MSG] RRCReject \n"); + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_RRC_UE, + ue_p->Srb0.Tx_buffer.Header, + ue_p->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" NR_RRCReject UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, + ue_p->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating NR_RRCReject (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_p->Srb0.Tx_buffer.payload_size); + +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, + ue_p->Srb0.Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); + GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#endif +} + +//----------------------------------------------------------------------------- +/* +* Process the rrc setup complete message from UE (SRB1 Active) +*/ +void +rrc_gNB_process_RRCSetupComplete( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + NR_RRCSetupComplete_IEs_t *rrcSetupComplete +) +//----------------------------------------------------------------------------- +{ + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing NR_RRCSetupComplete from UE (SRB1 Active)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + ue_context_pP->ue_context.Srb1.Active = 1; + ue_context_pP->ue_context.Status = NR_RRC_CONNECTED; + + if (AMF_MODE_ENABLED) { + rrc_gNB_send_NGAP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcSetupComplete); + } else { + rrc_gNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP); + } +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_defaultRRCReconfiguration( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP +) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + NR_SRB_ToAddModList_t **SRB_configList2 = NULL; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + NR_DRB_ToAddModList_t **DRB_configList = NULL; + NR_DRB_ToAddModList_t **DRB_configList2 = NULL; + NR_SRB_ToAddMod_t *SRB2_config = NULL; + NR_DRB_ToAddMod_t *DRB_config = NULL; + NR_SDAP_Config_t *sdap_config = NULL; + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList + *dedicatedNAS_MessageList = NULL; + NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; + + uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + + /******************** Radio Bearer Config ********************/ + /* Configure SRB2 */ + SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; + if (*SRB_configList2) { + free(*SRB_configList2); + } + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB2_config->srb_Identity = 2; + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + + /* Configure DRB */ + DRB_configList = &ue_context_pP->ue_context.DRB_configList; + if (*DRB_configList) { + free(*DRB_configList); + } + *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); + memset(*DRB_configList, 0, sizeof(**DRB_configList)); + + DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[xid]; + if (*DRB_configList2) { + free(*DRB_configList2); + } + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); + memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); + + DRB_config = CALLOC(1, sizeof(*DRB_config)); + DRB_config->drb_Identity = 1; + DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation)); + DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config; + // TODO sdap_Config + sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); + memset(sdap_config, 0, sizeof(NR_SDAP_Config_t)); + DRB_config->cnAssociation->choice.sdap_Config = sdap_config; + // TODO pdcp_Config + DRB_config->reestablishPDCP = NULL; + DRB_config->recoverPDCP = NULL; + DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config)); + DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb)); + DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer)); + *DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_ms30; + DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL)); + *DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; + DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL)); + *DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; + DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0; + + DRB_config->pdcp_Config->drb->integrityProtection = NULL; + DRB_config->pdcp_Config->drb->statusReportRequired = NULL; + DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL; + DRB_config->pdcp_Config->moreThanOneRLC = NULL; + + DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering)); + *DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; + DRB_config->pdcp_Config->ext1 = NULL; + + ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); + + dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); + + if (ue_context_pP->ue_context.nas_pdu_flag == 1) { + dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); + memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedNAS_Message, + (char *)ue_context_pP->ue_context.nas_pdu.buffer, + ue_context_pP->ue_context.nas_pdu.length); + ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + } + + /* If list is empty free the list and reset the address */ + if (dedicatedNAS_MessageList->list.count == 0) { + free(dedicatedNAS_MessageList); + dedicatedNAS_MessageList = NULL; + } + + memset(buffer, 0, RRC_BUF_SIZE); + size = do_RRCReconfiguration(ctxt_pP, buffer, + xid, + *SRB_configList2, + *DRB_configList, + NULL, + NULL, + NULL, + NULL, + dedicatedNAS_MessageList, + NULL); + + free(ue_context_pP->ue_context.nas_pdu.buffer); + + LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n"); + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + size, + ue_context_pP->ue_context.rnti); + LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, + ctxt_pP->module_id, + size, + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + ctxt_pP->module_id, + DCCH); + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" NR_RRCReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#else + nr_rrc_data_req(ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif + // rrc_pdcp_config_asn1_req + // rrc_rlc_config_asn1_req +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_dedicatedRRCReconfiguration_release( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t xid, + uint32_t nas_length, + uint8_t *nas_buffer) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[RRC_BUF_SIZE]; + int i; + uint16_t size = 0; + NR_DRB_ToReleaseList_t **DRB_Release_configList2 = NULL; + NR_DRB_Identity_t *DRB_release; + struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList + *dedicatedNAS_MessageList = NULL; + NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL; + + DRB_Release_configList2 = &ue_context_pP->ue_context.DRB_Release_configList2[xid]; + if (*DRB_Release_configList2) { + free(*DRB_Release_configList2); + } + + *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2)); + for(i = 0; i < NB_RB_MAX; i++) { + if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) { + DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t)); + *DRB_release = i+1; + ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release); + } + } + + /* If list is empty free the list and reset the address */ + if (nas_length > 0) { + dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); + dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); + memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedNAS_Message, + (char *)nas_buffer, + nas_length); + ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + LOG_I(NR_RRC,"add NAS info with size %d\n", nas_length); + } else { + LOG_W(NR_RRC,"dedlicated NAS list is empty\n"); + } + + memset(buffer, 0, RRC_BUF_SIZE); + size = do_RRCReconfiguration(ctxt_pP, buffer, xid, + NULL, + NULL, + *DRB_Release_configList2, + NULL, + NULL, + NULL, + dedicatedNAS_MessageList, + NULL); + + ue_context_pP->ue_context.pdu_session_release_command_flag = 1; + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Reconfiguration\n"); + + /* Free all NAS PDUs */ + if (nas_length > 0) { + /* Free the NAS PDU buffer and invalidate it */ + free(nas_buffer); + } + + LOG_I(NR_RRC, + "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE RNTI %x)\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_D(NR_RRC, + "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" dedicated NR_RRCReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#else + nr_rrc_data_req( + ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif +} + +//----------------------------------------------------------------------------- +/* +* Process the RRC Reconfiguration Complete from the UE +*/ +void +rrc_gNB_process_RRCReconfigurationComplete( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t xid +) +{ + int drb_id; + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + uint8_t *kUPenc = NULL; + NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; + NR_DRB_Identity_t *drb_id_p = NULL; +// uint8_t nr_DRB2LCHAN[8]; + + ue_context_pP->ue_context.ue_reestablishment_timer = 0; + +#ifndef PHYSIM + /* Derive the keys from kgnb */ + if (DRB_configList != NULL) { + derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kUPenc); + } + + derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCenc); + derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCint); +#endif + /* Refresh SRBs/DRBs */ + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_PDCP_ENB, NULL, 0, MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti); + +#ifndef ITTI_SIM + nr_rrc_pdcp_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2, + 0xff, // already configured during the securitymodecommand + kRRCenc, + kRRCint, + kUPenc, + NULL, + NULL, + NULL); + /* Refresh SRBs/DRBs */ + nr_rrc_rlc_config_asn1_req(ctxt_pP, + SRB_configList, // NULL, + DRB_configList, + DRB_Release_configList2, + NULL, + NULL); +#endif + + /* Set the SRB active in UE context */ + if (SRB_configList != NULL) { + for (int i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { + if (SRB_configList->list.array[i]->srb_Identity == 1) { + ue_context_pP->ue_context.Srb1.Active = 1; + } else if (SRB_configList->list.array[i]->srb_Identity == 2) { + ue_context_pP->ue_context.Srb2.Active = 1; + ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; + LOG_I(NR_RRC,"[gNB %d] Frame %d CC %d : SRB2 is now active\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ue_context_pP->ue_context.primaryCC_id); + } else { + LOG_W(NR_RRC,"[gNB %d] Frame %d CC %d : invalide SRB identity %ld\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ue_context_pP->ue_context.primaryCC_id, + SRB_configList->list.array[i]->srb_Identity); + } + } + + free(SRB_configList); + ue_context_pP->ue_context.SRB_configList2[xid] = NULL; + } + + /* Loop through DRBs and establish if necessary */ + if (DRB_configList != NULL) { + for (int i = 0; i < DRB_configList->list.count; i++) { + if (DRB_configList->list.array[i]) { + drb_id = (int)DRB_configList->list.array[i]->drb_Identity; + LOG_I(NR_RRC, "[gNB %d] Frame %d : Logical Channel UL-DCCH, Received NR_RRCReconfigurationComplete from UE rnti %x, reconfiguring DRB %d\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ctxt_pP->rnti, + (int)DRB_configList->list.array[i]->drb_Identity); + //(int)*DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel); + + if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) { + ue_context_pP->ue_context.DRB_active[drb_id] = 1; + LOG_D(NR_RRC, "[gNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", + ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); + + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (DRB) ---> MAC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + //if (DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel) { + // nr_DRB2LCHAN[i] = (uint8_t) * DRB_configList->list.array[i]->pdcp_Config->moreThanOneRLC->primaryPath.logicalChannel; + //} + + // rrc_mac_config_req_eNB + } else { // remove LCHAN from MAC/PHY + if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { + /* TODO : It may be needed if gNB goes into full stack working. */ + // DRB has just been removed so remove RLC + PDCP for DRB + /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, + (ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE); + */ + /*rrc_rlc_config_req(ctxt_pP, + SRB_FLAG_NO, + MBMS_FLAG_NO, + CONFIG_ACTION_REMOVE, + nr_DRB2LCHAN[i], + Rlc_info_um);*/ + } + + ue_context_pP->ue_context.DRB_active[drb_id] = 0; + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + // rrc_mac_config_req_eNB + + } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) + } // end if (DRB_configList->list.array[i]) + } // end for (int i = 0; i < DRB_configList->list.count; i++) + + free(DRB_configList); + ue_context_pP->ue_context.DRB_configList2[xid] = NULL; + } // end if DRB_configList != NULL + + if(DRB_Release_configList2 != NULL) { + for (int i = 0; i < DRB_Release_configList2->list.count; i++) { + if (DRB_Release_configList2->list.array[i]) { + drb_id_p = DRB_Release_configList2->list.array[i]; + drb_id = *drb_id_p; + + if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { + ue_context_pP->ue_context.DRB_active[drb_id] = 0; + } + } + } + + free(DRB_Release_configList2); + ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; + } +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_RRCReestablishment( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const int CC_id) +//----------------------------------------------------------------------------- +{ + // int UE_id = -1; + //NR_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; + NR_SRB_ToAddModList_t **SRB_configList; + // NR_SRB_ToAddMod_t *SRB1_config = NULL; + //rrc_gNB_carrier_data_t *carrier = NULL; + gNB_RRC_UE_t *ue_context = NULL; + module_id_t module_id = ctxt_pP->module_id; + // uint16_t rnti = ctxt_pP->rnti; + + SRB_configList = &(ue_context_pP->ue_context.SRB_configList); + //carrier = &(RC.nrrrc[ctxt_pP->module_id]->carrier); + ue_context = &(ue_context_pP->ue_context); + ue_context->Srb0.Tx_buffer.payload_size = do_RRCReestablishment(ctxt_pP, + ue_context_pP, + CC_id, + (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, + //(uint8_t) carrier->p_gNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2 + rrc_gNB_get_next_transaction_identifier(module_id), + SRB_configList + //&(ue_context->physicalConfigDedicated) + ); + + /* Configure SRB1 for UE */ + if (*SRB_configList != NULL) { + for (int cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { + if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) { + // SRB1_config = (*SRB_configList)->list.array[cnt]; + } + + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + // rrc_mac_config_req_eNB + } + } // if (*SRB_configList != NULL) + + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_RRC_UE, + ue_context->Srb0.Tx_buffer.Header, + ue_context->Srb0.Tx_buffer.payload_size, + MSC_AS_TIME_FMT" NR_RRCReestablishment UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context->rnti, + ue_context->Srb0.Tx_buffer.payload_size); + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context->Srb0.Tx_buffer.payload_size); +#if(0) + /* TODO : It may be needed if gNB goes into full stack working. */ + UE_id = find_nr_UE_id(module_id, rnti); + if (UE_id != -1) { + /* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */ + RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; + /* Reject UE after 10 frames, LTE_RRCConnectionReestablishmentReject is triggered */ + RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 100; + } else { + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Generating NR_RRCReestablishment without UE_id(MAC) rnti %x\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + rnti); + } +#endif +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, ue_context->Srb0.Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, ue_context->Srb0.Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = ue_context->Srb0.Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#endif + +} + +//----------------------------------------------------------------------------- +void +rrc_gNB_process_RRCConnectionReestablishmentComplete( + const protocol_ctxt_t *const ctxt_pP, + const rnti_t reestablish_rnti, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t xid +) +//----------------------------------------------------------------------------- +{ + LOG_I(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing NR_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + + NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + NR_SRB_ToAddModList_t **SRB_configList2 = NULL; + NR_DRB_ToAddModList_t **DRB_configList2 = NULL; + NR_SRB_ToAddMod_t *SRB2_config = NULL; + NR_DRB_ToAddMod_t *DRB_config = NULL; + //NR_SDAP_Config_t *sdap_config = NULL; + int i = 0; + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size; + + uint8_t next_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); + int ret = 0; + ue_context_pP->ue_context.Status = NR_RRC_CONNECTED; + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED + ue_context_pP->ue_context.reestablishment_xid = next_xid; + SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; + + // get old configuration of SRB2 + if (*SRB_configList2 != NULL) { + if((*SRB_configList2)->list.count!=0) { + LOG_D(NR_RRC, "SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p", + SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); + } + + for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { + if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { + LOG_D(NR_RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid); + SRB2_config = (*SRB_configList2)->list.array[i]; + break; + } + } + } + + // SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + // SRB2_config->srb_Identity = 2; + + SRB_configList2 = &(ue_context_pP->ue_context.SRB_configList2[next_xid]); + DRB_configList2 = &(ue_context_pP->ue_context.DRB_configList2[next_xid]); + + if (*SRB_configList2) { + free(*SRB_configList2); + LOG_D(NR_RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid); + } + + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + + if (SRB2_config != NULL) { + // Add SRB2 to SRB configuration list + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n", + SRB2_config->srb_Identity); + LOG_D(NR_RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", + SRB2_config->srb_Identity, next_xid); + } else { + // SRB configuration list only contains SRB1. + LOG_W(NR_RRC,"SRB2 configuration does not exist in SRB configuration list\n"); + } + + if (*DRB_configList2) { + free(*DRB_configList2); + LOG_D(NR_RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid); + } + + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); + + if (DRB_configList != NULL) { + LOG_D(NR_RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n"); + + for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) { + DRB_config = DRB_configList->list.array[i]; + // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete + ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); + } + } + + ue_context_pP->ue_context.Srb1.Active = 1; + //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; + + if (AMF_MODE_ENABLED) { + hashtable_rc_t h_rc; + int j; + rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; + uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + uint32_t gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + gNB_RRC_INST *rrc_instance_p = RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]; + + if (gNB_ue_ngap_id > 0) { + h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p); + + if (h_rc == HASH_TABLE_OK) { + rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti; + } + } + + if (ue_initial_id != 0) { + h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p); + + if (h_rc == HASH_TABLE_OK) { + rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti; + } + } + + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + /* Save e RAB information for later */ + memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); + + for ( j = 0, i = 0; i < NB_RB_MAX; i++) { + if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) { + create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pdusession[i].param.pdusession_id; + create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pdusession[i].param.gtp_teid; + memcpy(create_tunnel_req.upf_addr[j].buffer, + ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer, + sizeof(uint8_t)*20); + create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length; + j++; + } + } + + create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above + create_tunnel_req.num_tunnels = j; + ret = gtpv1u_update_ngu_tunnel( + ctxt_pP->instance, + &create_tunnel_req, + reestablish_rnti); + + if ( ret != 0 ) { + LOG_E(NR_RRC,"gtpv1u_update_ngu_tunnel failed,start to release UE %x\n",reestablish_rnti); + + // update s1u tunnel failed,reset rnti? + if (gNB_ue_ngap_id > 0) { + h_rc = hashtable_get(rrc_instance_p->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id, (void **)&rrc_ue_ngap_ids_p); + + if (h_rc == HASH_TABLE_OK ) { + rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti; + } + } + + if (ue_initial_id != 0) { + h_rc = hashtable_get(rrc_instance_p->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_ngap_ids_p); + + if (h_rc == HASH_TABLE_OK ) { + rrc_ue_ngap_ids_p->ue_rnti = reestablish_rnti; + } + } + + ue_context_pP->ue_context.ue_release_timer_s1 = 1; + ue_context_pP->ue_context.ue_release_timer_thres_s1 = 100; + ue_context_pP->ue_context.ue_release_timer = 0; + ue_context_pP->ue_context.ue_reestablishment_timer = 0; + ue_context_pP->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + ue_context_pP->ue_context.ul_failure_timer = 0; + return; + } + } /* AMF_MODE_ENABLED */ + + /* Update RNTI in ue_context */ + ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else + ue_context_pP->ue_context.rnti = ctxt_pP->rnti; + + if (AMF_MODE_ENABLED) { + uint8_t send_security_mode_command = FALSE; + nr_rrc_pdcp_config_security( + ctxt_pP, + ue_context_pP, + send_security_mode_command); + LOG_D(NR_RRC, "set security successfully \n"); + } + + /* Add all NAS PDUs to the list */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { + + /* TODO parameters yet to process ... */ + /* TODO should test if pdu session are Ok before! */ + ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE; + ue_context_pP->ue_context.pdusession[i].xid = xid; + LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE"); + } + + memset(buffer, 0, RRC_BUF_SIZE); + + size = do_RRCReconfiguration(ctxt_pP, buffer, + xid, + *SRB_configList2, + DRB_configList, + NULL, + NULL, + NULL, + NULL, // MeasObj_list, + NULL, + NULL); + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Reconfiguration\n"); + + /* Free all NAS PDUs */ + for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { + if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) { + /* Free the NAS PDU buffer and invalidate it */ + free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL; + } + } + + if(size==65535) { + LOG_E(NR_RRC,"RRC decode err!!! do_RRCReconfiguration\n"); + return; + } else { + LOG_I(NR_RRC, + "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + LOG_D(NR_RRC, + "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", + ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#else + nr_rrc_data_req( + ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif + } +} +//----------------------------------------------------------------------------- + +/*------------------------------------------------------------------------------*/ +int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, + const uint8_t *buffer, + int buffer_length, + const int CC_id) +{ + module_id_t Idx; + asn_dec_rval_t dec_rval; + NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; + NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; + NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; + uint64_t random_value = 0; + int i; + + dec_rval = uper_decode( NULL, + &asn_DEF_NR_UL_CCCH_Message, + (void **)&ul_ccch_msg, + (uint8_t *) buffer, + 100, + 0, + 0); + + if (dec_rval.consumed == 0) { + /* TODO */ + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + return -1; + } + + if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { + switch (ul_ccch_msg->message.choice.c1->present) { + case NR_UL_CCCH_MessageType__c1_PR_NOTHING: + /* TODO */ + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", + PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest: + LOG_I(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti); + ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti); + if (ue_context_p != NULL) { + rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p); + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + dec_rval.consumed, + MSC_AS_TIME_FMT" NR_RRCSetupRequest UE %x size %u (UE already in context)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + dec_rval.consumed); + } else { + rrcSetupRequest = &ul_ccch_msg->message.choice.c1->choice.rrcSetupRequest->rrcSetupRequest; + if (NR_InitialUE_Identity_PR_randomValue == rrcSetupRequest->ue_Identity.present) { + /* randomValue BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.randomValue.size != 5) { // 39-bit random value + LOG_E(NR_RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.randomValue.size); + return -1; + } + + memcpy(((uint8_t *) & random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); + + /* if there is already a registered UE (with another RNTI) with this random_value, + * the current one must be removed from MAC/PHY (zombie UE) + */ + if ((ue_context_p = rrc_gNB_ue_context_random_exist(RC.nrrrc[ctxt_pP->module_id], random_value))) { + LOG_W(NR_RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n", + ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; + } + + ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); + ue_context_p->ue_context.Srb0.Srb_id = 0; + ue_context_p->ue_context.Srb0.Active = 1; + memcpy(ue_context_p->ue_context.Srb0.Rx_buffer.Payload, + buffer, + buffer_length); + ue_context_p->ue_context.Srb0.Rx_buffer.payload_size = buffer_length; + } else if (NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1 == rrcSetupRequest->ue_Identity.present) { + /* TODO */ + /* <5G-S-TMSI> = <5G-TMSI> 48-bit */ + /* ng-5G-S-TMSI-Part1 BIT STRING (SIZE (39)) */ + if (rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size != 5) { + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part1 size, expected 5, provided %lu \n", + (long unsigned int)rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + return -1; + } + + uint64_t s_tmsi_part1 = bitStr_to_uint64(&rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1); + + // memcpy(((uint8_t *) & random_value) + 3, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.buf, + // rrcSetupRequest->ue_Identity.choice.ng_5G_S_TMSI_Part1.size); + + if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1))) { + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p, ue_context_p->ue_context.rnti, ctxt_pP->rnti); + + nr_rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); + + /* replace rnti in the context */ + /* for that, remove the context from the RB tree */ + RB_REMOVE(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + /* and insert again, after changing rnti everywhere it has to be changed */ + ue_context_p->ue_id_rnti = ctxt_pP->rnti; + ue_context_p->ue_context.rnti = ctxt_pP->rnti; + RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + /* reset timers */ + ue_context_p->ue_context.ul_failure_timer = 0; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ue_release_timer_s1 = 0; + ue_context_p->ue_context.ue_release_timer_rrc = 0; + } else { + LOG_I(NR_RRC, " 5G-S-TMSI-Part1 doesn't exist, setting ng_5G_S_TMSI_Part1 to %p => %ld\n", + ue_context_p, s_tmsi_part1); + + ue_context_p = rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], s_tmsi_part1); + + if (ue_context_p == NULL) { + LOG_E(RRC, "%s:%d:%s: rrc_gNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); + } + + if (ue_context_p != NULL) { + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE; + ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; + } + } + } else { + /* TODO */ + memcpy(((uint8_t *) & random_value) + 3, + rrcSetupRequest->ue_Identity.choice.randomValue.buf, + rrcSetupRequest->ue_Identity.choice.randomValue.size); + + rrc_gNB_get_next_free_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], random_value); + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_gNB_generate_RRCReject(ctxt_pP, + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), + CC_id); + break; + } + } + + if (ue_context_p != NULL) { + ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause; + } + + rrc_gNB_generate_RRCSetup(ctxt_pP, + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), + CC_id); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest: + LOG_I(NR_RRC, "receive rrcResumeRequest message \n"); + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcReestablishmentRequest: + LOG_I(NR_RRC, "receive rrcReestablishmentRequest message \n"); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)(buffer), buffer_length, + "[MSG] RRC Reestablishment Request\n"); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT"MAC_gNB--- MAC_DATA_IND (rrcReestablishmentRequest on SRB0) --> RRC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + + rrcReestablishmentRequest = ul_ccch_msg->message.choice.c1->choice.rrcReestablishmentRequest->rrcReestablishmentRequest; + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest cause %s\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ((rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_otherFailure) ? "Other Failure" : + (rrcReestablishmentRequest.reestablishmentCause == NR_ReestablishmentCause_handoverFailure) ? "Handover Failure" : + "reconfigurationFailure")); + { + uint16_t c_rnti = 0; + if (rrcReestablishmentRequest.ue_Identity.physCellId != RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId) { + /* UE was moving from previous cell so quickly that RRCReestablishment for previous cell was recieved in this cell */ + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), fallback to RRC establishment\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + rrcReestablishmentRequest.ue_Identity.physCellId, + RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + break; + } + + LOG_D(NR_RRC, "physCellId is %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId); + + for (i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { + LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", + i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); + } + + if (rrcReestablishmentRequest.ue_Identity.c_RNTI < 0 || + rrcReestablishmentRequest.ue_Identity.c_RNTI > 65535) { + /* c_RNTI range error should not happen */ + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + break; + } + + c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; + LOG_I(NR_RRC, "c_rnti is %x\n", c_rnti); + ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, c_rnti); + + if (ue_context_p == NULL) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + break; + } +#if(0) + /* TODO : It may be needed if gNB goes into full stack working. */ + int UE_id = find_nr_UE_id(ctxt_pP->module_id, c_rnti); + + if(UE_id == -1) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE_id(MAC) rnti %x, fallback to RRC establishment\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + break; + } + + //previous rnti + rnti_t previous_rnti = 0; + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (reestablish_rnti_map[i][1] == c_rnti) { + previous_rnti = reestablish_rnti_map[i][0]; + break; + } + } + + if(previous_rnti != 0) { + UE_id = find_nr_UE_id(ctxt_pP->module_id, previous_rnti); + + if(UE_id == -1) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCReestablishmentRequest without UE_id(MAC) previous rnti %x, fallback to RRC establishment\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + break; + } + } +#endif + //c-plane not end + if((ue_context_p->ue_context.Status != NR_RRC_RECONFIGURED) && (ue_context_p->ue_context.reestablishment_cause == NR_ReestablishmentCause_spare1)) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed \n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); + /* TODO RRC Release ? */ + break; + } + + if(ue_context_p->ue_context.ue_reestablishment_timer > 0) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RRRCReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status NR_RRC_RECONFIGURED\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->ue_context.Status + ); + ue_context_p->ue_context.Status = NR_RRC_RECONFIGURED; + protocol_ctxt_t ctxt_old_p; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, + ctxt_pP->instance, + GNB_FLAG_YES, + c_rnti, + ctxt_pP->frame, + ctxt_pP->subframe); + rrc_gNB_process_RRCReconfigurationComplete(&ctxt_old_p, + ue_context_p, + ue_context_p->ue_context.reestablishment_xid); + + for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) { + if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { + ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; + } else { + ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; + } + } + } + + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" UE context: %p\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p); + /* reset timers */ + ue_context_p->ue_context.ul_failure_timer = 0; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + // ue_context_p->ue_context.ue_release_timer_s1 = 0; + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_context_p->ue_context.reestablishment_xid = -1; + + // insert C-RNTI to map + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (reestablish_rnti_map[i][0] == 0) { + reestablish_rnti_map[i][0] = ctxt_pP->rnti; + reestablish_rnti_map[i][1] = c_rnti; + LOG_D(NR_RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", + i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); + break; + } + } + + ue_context_p->ue_context.reestablishment_cause = rrcReestablishmentRequest.reestablishmentCause; + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Accept reestablishment request from UE physCellId %ld cause %ld\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + rrcReestablishmentRequest.ue_Identity.physCellId, + ue_context_p->ue_context.reestablishment_cause); + + ue_context_p->ue_context.primaryCC_id = CC_id; + //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; + Idx = DCCH; + // SRB1 + ue_context_p->ue_context.Srb1.Active = 1; + ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + // SRB2: set it to go through SRB1 with id 1 (DCCH) + ue_context_p->ue_context.Srb2.Active = 1; + ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + + rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, CC_id); + + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + Idx); + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_PDCP_GNB, + NULL, + 0, + MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti); + // nr_rrc_pdcp_config_asn1_req(ctxt_pP, + // ue_context_p->ue_context.SRB_configList, + // NULL, + // NULL, + // 0xff, + // NULL, + // NULL, + // NULL, + // NULL, + // NULL, + // NULL); + + // if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { + // nr_rrc_rlc_config_asn1_req(ctxt_pP, + // ue_context_p->ue_context.SRB_configList, + // NULL, + // NULL, + // NULL, + // NULL); + // } + } + break; + + case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: + LOG_I(NR_RRC, "receive rrcSystemInfoRequest message \n"); + /* TODO */ + break; + + default: + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Unknown message\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + break; + } + } + return 0; +} + +/*! \fn uint64_t bitStr_to_uint64(BIT_STRING_t *) + *\brief This function extract at most a 64 bits value from a BIT_STRING_t object, the exact bits number depend on the BIT_STRING_t contents. + *\param[in] pointer to the BIT_STRING_t object. + *\return the extracted value. + */ +static inline uint64_t bitStr_to_uint64(BIT_STRING_t *asn) { + uint64_t result = 0; + int index; + int shift; + + DevCheck ((asn->size > 0) && (asn->size <= 8), asn->size, 0, 0); + + shift = ((asn->size - 1) * 8) - asn->bits_unused; + for (index = 0; index < (asn->size - 1); index++) { + result |= (uint64_t)asn->buf[index] << shift; + shift -= 8; + } + + result |= asn->buf[index] >> asn->bits_unused; + + return result; +} + +//----------------------------------------------------------------------------- +int +rrc_gNB_decode_dcch( + const protocol_ctxt_t *const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t *const Rx_sdu, + const sdu_size_t sdu_sizeP +) +//----------------------------------------------------------------------------- +{ + asn_dec_rval_t dec_rval; + NR_UL_DCCH_Message_t *ul_dcch_msg = NULL; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint8_t xid; + + int i; + + if ((Srb_id != 1) && (Srb_id != 2)) { + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld, should not have ...\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + Srb_id); + } else { + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received message on SRB%ld\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + Srb_id); + } + + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + dec_rval = uper_decode( + NULL, + &asn_DEF_NR_UL_DCCH_Message, + (void **)&ul_dcch_msg, + Rx_sdu, + sdu_sizeP, + 0, + 0); + // xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); + + { + for (i = 0; i < sdu_sizeP; i++) { + LOG_T(NR_RRC, "%x.", Rx_sdu[i]); + } + + LOG_T(NR_RRC, "\n"); + } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode UL-DCCH (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + return -1; + } + + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], + ctxt_pP->rnti); + + if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { + switch (ul_dcch_msg->message.choice.c1->present) { + case NR_UL_DCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_FMT" Received PR_NOTHING on UL-DCCH-Message\n", + PROTOCOL_NR_RRC_CTXT_ARGS(ctxt_pP)); + break; + + case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: + LOG_I(NR_RRC, "Receive RRC Reconfiguration Complete message UE %x\n", ctxt_pP->rnti); + if(!ue_context_p) { + LOG_E(NR_RRC, "Processing NR_RRCReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(Rx_sdu), sdu_sizeP, + "[MSG] RRC Connection Reconfiguration Complete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" NR_RRCReconfigurationComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(RRCReconfigurationComplete) ---> RRC_gNB]\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if (ul_dcch_msg->message.choice.c1->present == NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete) { + if (ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->criticalExtensions.present == + NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete) + rrc_gNB_process_RRCReconfigurationComplete( + ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); + } + + if (AMF_MODE_ENABLED) { + if(ue_context_p->ue_context.pdu_session_release_command_flag == 1) { + xid = ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier; + ue_context_p->ue_context.pdu_session_release_command_flag = 0; + //gtp tunnel delete + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, 0, GTPV1U_GNB_DELETE_TUNNEL_REQ); + memset(>PV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for(i = 0; i < NB_RB_MAX; i++) { + if(xid == ue_context_p->ue_context.pdusession[i].xid) { + GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = + ue_context_p->ue_context.gnb_gtp_psi[i]; + ue_context_p->ue_context.gnb_gtp_teid[i] = 0; + memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i])); + ue_context_p->ue_context.gnb_gtp_psi[i] = 0; + } + } + + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p); + //NGAP_PDUSESSION_RELEASE_RESPONSE + rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid); + } else { + rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); + } + } + + if (first_rrcreconfiguration == 0){ + first_rrcreconfiguration = 1; + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); + } + + break; + + case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete: + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing NR_RRCSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC SetupComplete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" NR_RRCSetupComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(RRCSetupComplete) ---> RRC_gNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.present == + NR_RRCSetupComplete__criticalExtensions_PR_rrcSetupComplete) { + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value != NULL) { + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2) { + // ng-5G-S-TMSI-Part2 BIT STRING (SIZE (9)) + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size != 2) { + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI_Part2 size, expected 2, provided %lu", + (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete-> + ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2.size); + return -1; + } + + if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 != 0) { + ue_context_p->ue_context.ng_5G_S_TMSI_Part2 = + BIT_STRING_to_uint16(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete-> + ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2); + } + + /* TODO */ + } else if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->present == NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI) { + // NG-5G-S-TMSI ::= BIT STRING (SIZE (48)) + if (ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice. + rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size != 6) { + LOG_E(NR_RRC, "wrong ng_5G_S_TMSI size, expected 6, provided %lu", + (long unsigned int)ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete-> + ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI.size); + return -1; + } + + uint64_t fiveg_s_TMSI = bitStr_to_uint64(&ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete-> + criticalExtensions.choice.rrcSetupComplete->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); + LOG_I(NR_RRC, "Received rrcSetupComplete, 5g_s_TMSI: 0x%lX, amf_set_id: 0x%lX(%ld), amf_pointer: 0x%lX(%ld), 5g TMSI: 0x%X \n", + fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, + (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, + (uint32_t)fiveg_s_TMSI); + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; + } + } + } + + rrc_gNB_process_RRCSetupComplete( + ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcSetupComplete->criticalExtensions.choice.rrcSetupComplete); + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" UE State = NR_RRC_CONNECTED \n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + } + + ue_context_p->ue_context.ue_release_timer = 0; + break; + + case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + LOG_I(NR_RRC,"Recived RRC GNB UL Information Transfer \n"); + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing ulInformationTransfer UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_D(NR_RRC,"[MSG] RRC UL Information Transfer \n"); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC UL Information Transfer \n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" ulInformationTransfer UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + + if (AMF_MODE_ENABLED == 1) { + rrc_gNB_send_NGAP_UPLINK_NAS(ctxt_pP, + ue_context_p, + ul_dcch_msg); + } + break; + + case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: + // to avoid segmentation fault + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeComplete) ---> RRC_eNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + + rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); + //rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + break; + case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] NR RRC Security Mode Failure\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" securityModeFailure UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_W(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeFailure) ---> RRC_gNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + + rrc_gNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); + break; + + case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + if(!ue_context_p) { + LOG_I(NR_RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] NR_RRC UECapablility Information\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" ueCapabilityInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + LOG_D(RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(UECapabilityInformation) ---> RRC_eNB\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)ul_dcch_msg); + } + LOG_I(NR_RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); + int eutra_index = -1; + + if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == + NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { + for(i = 0;i < ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count; i++){ + if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_nr){ + if(ue_context_p->ue_context.UE_Capability_nr){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_nr, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + ue_context_p->ue_context.UE_Capability_size = + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + if(eutra_index != -1){ + LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); + exit(1); + } + eutra_index = i; + } + + if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra_nr){ + if(ue_context_p->ue_context.UE_Capability_MRDC){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_MRDC, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + ue_context_p->ue_context.UE_MRDC_Capability_size = + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + } + + if(ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra){ + //TODO + } + } + + if(eutra_index == -1) + break; + } + if (AMF_MODE_ENABLED == 1) { + rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(ctxt_pP, + ue_context_p, + ul_dcch_msg); + } + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + break; + + case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] NR_RRC Connection Reestablishment Complete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" NR_RRCConnectionReestablishmentComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_I(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(rrcConnectionReestablishmentComplete) ---> RRC_gNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + { + rnti_t reestablish_rnti = 0; + + // select C-RNTI from map + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) { + reestablish_rnti = reestablish_rnti_map[i][1]; + ue_context_p = rrc_gNB_get_ue_context( + RC.nrrrc[ctxt_pP->module_id], + reestablish_rnti); + // clear currentC-RNTI from map + reestablish_rnti_map[i][0] = 0; + reestablish_rnti_map[i][1] = 0; + LOG_D(NR_RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", + i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); + break; + } + } + + if (!ue_context_p) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCConnectionReestablishmentComplete without UE context, falt\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + break; + } + +#if(0) + /* TODO : It may be needed if gNB goes into full stack working. */ + //clear + int UE_id = find_nr_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); + + if(UE_id == -1) { + LOG_E(NR_RRC, + PROTOCOL_RRC_CTXT_UE_FMT" NR_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + break; + } + + RC.nrmac[ctxt_pP->module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; +#endif + ue_context_p->ue_context.reestablishment_xid = -1; + + if (ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->criticalExtensions.present == + NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete) { + rrc_gNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete->rrc_TransactionIdentifier); + + } + + //ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 1; + // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered + ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000; + } + break; + default: + break; + } + } + return 0; +} + void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) { gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; @@ -319,7 +2261,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { /* send a tick to x2ap */ if (is_x2ap_enabled()){ - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_SUBFRAME_PROCESS); itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); } } @@ -333,7 +2275,7 @@ void *rrc_gnb_task(void *args_p) { int result; //SRB_INFO *srb_info_p; //int CC_id; - //protocol_ctxt_t ctxt; + protocol_ctxt_t ctxt; itti_mark_task_ready(TASK_RRC_GNB); LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n"); @@ -341,7 +2283,7 @@ void *rrc_gnb_task(void *args_p) { // Wait for a message itti_receive_msg(TASK_RRC_GNB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); - instance = ITTI_MSG_INSTANCE(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) @@ -349,21 +2291,76 @@ void *rrc_gnb_task(void *args_p) { switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: - LOG_W(RRC, " *** Exiting NR_RRC thread\n"); + LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); itti_exit_task(); break; case MESSAGE_TEST: - LOG_I(RRC, "[gNB %d] Received %s\n", instance, msg_name_p); + LOG_I(NR_RRC, "[gNB %ld] Received %s\n", instance, msg_name_p); break; - /* Messages from MAC */ - case RRC_SUBFRAME_PROCESS: nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); break; + /* Messages from MAC */ + case NR_RRC_MAC_CCCH_DATA_IND: + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index, + GNB_FLAG_YES, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti, + msg_p->ittiMsgHeader.lte_time.frame, + msg_p->ittiMsgHeader.lte_time.slot); + LOG_I(NR_RRC,"Decoding CCCH : inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", + instance, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id, + &ctxt, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); + + if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) { + LOG_I(NR_RRC, "CCCH message has size %d > %d\n", + NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,CCCH_SDU_SIZE); + break; + } + + nr_rrc_gNB_decode_ccch(&ctxt, + (uint8_t *)NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, + NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id); + break; + /* Messages from PDCP */ + case NR_RRC_DCCH_DATA_IND: + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + instance, + GNB_FLAG_YES, + NR_RRC_DCCH_DATA_IND(msg_p).rnti, + msg_p->ittiMsgHeader.lte_time.frame, + msg_p->ittiMsgHeader.lte_time.slot); + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), + NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, + msg_name_p); + rrc_gNB_decode_dcch(&ctxt, + NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, + NR_RRC_DCCH_DATA_IND(msg_p).sdu_size); + break; + + case NGAP_DOWNLINK_NAS: + rrc_gNB_process_NGAP_DOWNLINK_NAS(msg_p, msg_name_p, instance, &rrc_gNB_mui); + break; + + case NGAP_PDUSESSION_SETUP_REQ: + rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(msg_p, msg_name_p, instance); + break; + + case NGAP_PDUSESSION_RELEASE_COMMAND: + rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND(msg_p, msg_name_p, instance); + break; + + case GTPV1U_GNB_DELETE_TUNNEL_RESP: + break; /* #if defined(ENABLE_USE_MME) @@ -422,7 +2419,7 @@ void *rrc_gnb_task(void *args_p) { */ /* Messages from gNB app */ case NRRRC_CONFIGURATION_REQ: - LOG_I(NR_RRC, "[gNB %d] Received %s : %p\n", instance, msg_name_p,&NRRRC_CONFIGURATION_REQ(msg_p)); + LOG_I(NR_RRC, "[gNB %ld] Received %s : %p\n", instance, msg_name_p,&NRRRC_CONFIGURATION_REQ(msg_p)); openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(instance), &NRRRC_CONFIGURATION_REQ(msg_p)); break; @@ -436,6 +2433,10 @@ void *rrc_gnb_task(void *args_p) { LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n"); break; + case NGAP_INITIAL_CONTEXT_SETUP_REQ: + rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p, msg_name_p, instance); + break; + case X2AP_ENDC_SGNB_RELEASE_REQUEST: LOG_I(NR_RRC, "Received ENDC sgNB release request from X2AP \n"); rrc_gNB_process_release_request(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p)); @@ -450,8 +2451,16 @@ void *rrc_gnb_task(void *args_p) { /* nothing to do? */ break; + case NGAP_UE_CONTEXT_RELEASE_REQ: + rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance); + break; + + case NGAP_UE_CONTEXT_RELEASE_COMMAND: + rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p, msg_name_p, instance); + break; + default: - LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p); + LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); break; } @@ -461,10 +2470,202 @@ void *rrc_gnb_task(void *args_p) { } } +//----------------------------------------------------------------------------- +void +rrc_gNB_generate_SecurityModeCommand( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[100]; + uint8_t size; + T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_context_pP->ue_context.integrity_algorithm; + size = do_NR_SecurityModeCommand( + ctxt_pP, + buffer, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + ue_context_pP->ue_context.ciphering_algorithm, + &integrity_algorithm); + LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + size); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (securityModeCommand to UE MUI %d) --->[PDCP][RB %02d]\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + rrc_gNB_mui, + DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" securityModeCommand UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); + + LOG_I(NR_RRC,"calling rrc_data_req :securityModeCommand\n"); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#else + nr_rrc_data_req(ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif + +} + +void +rrc_gNB_generate_UECapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[100]; + uint8_t size; + T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + size = do_NR_SA_UECapabilityEnquiry( + ctxt_pP, + buffer, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (NR UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + rrc_gNB_mui, + DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" rrcNRUECapabilityEnquiry UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#else + nr_rrc_data_req( + ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif +} + +//----------------------------------------------------------------------------- +/* +* Generate the RRC Connection Release to UE. +* If received, UE should switch to RRC_IDLE mode. +*/ +void +rrc_gNB_generate_RRCRelease( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +) +//----------------------------------------------------------------------------- +{ + uint8_t buffer[RRC_BUF_SIZE]; + uint16_t size = 0; + + memset(buffer, 0, RRC_BUF_SIZE); + + size = do_NR_RRCRelease(buffer,rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); + ue_context_pP->ue_context.ue_reestablishment_timer = 0; + ue_context_pP->ue_context.ue_release_timer = 0; + LOG_I(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCRelease (bytes %d)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + size); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcRelease MUI %d) --->[PDCP][RB %u]\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + rrc_gNB_mui, + DCCH); + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_RRC_UE, + buffer, + size, + MSC_AS_TIME_FMT" NR_RRCRelease UE %x MUI %d size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_context.rnti, + rrc_gNB_mui, + size); + +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); +#else + if (NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; + F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer; + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size; + itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); + } else { + nr_rrc_data_req(ctxt_pP, + DCCH, + rrc_gNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } +#endif +} void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_RRC_GNB, RRC_SUBFRAME_PROCESS); + message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS); RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c index 9ab1bbf43a..293f9e8b9f 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.c +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -92,3 +92,52 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( return -1; } } + +int +nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +) { + rnti_t rnti; + int i; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + + if (create_tunnel_resp_pP) { + LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + create_tunnel_resp_pP->num_tunnels); + rnti = create_tunnel_resp_pP->rnti; + ue_context_p = rrc_gNB_get_ue_context( + RC.nrrrc[ctxt_pP->module_id], + ctxt_pP->rnti); + + for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { + ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->gnb_NGu_teid[i]; + ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->gnb_addr; + ue_context_p->ue_context.gnb_gtp_psi[inde_list[i]] = create_tunnel_resp_pP->pdusession_id[i]; + LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + create_tunnel_resp_pP->gnb_NGu_teid[i], + ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]], + inde_list[i], + i, + create_tunnel_resp_pP->pdusession_id[i], + create_tunnel_resp_pP->gnb_addr.length); + } + + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_GTPU_GNB, + NULL,0, + MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u psid %u enb-s1u teid %u", + 0,0,rnti, + create_tunnel_resp_pP->num_tunnels, + ue_context_p->ue_context.gnb_gtp_psi[0], + ue_context_p->ue_context.gnb_gtp_teid[0]); + (void)rnti; /* avoid gcc warning "set but not used" */ + return 0; + } else { + return -1; + } +} diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.h b/openair2/RRC/NR/rrc_gNB_GTPV1U.h index caff825a7a..748bd98789 100644 --- a/openair2/RRC/NR/rrc_gNB_GTPV1U.h +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.h @@ -37,3 +37,12 @@ rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, uint8_t *inde_list ); + +int +nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +); + +#endif diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c new file mode 100644 index 0000000000..c6778729ec --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -0,0 +1,1403 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file rrc_gNB_NGAP.h + * \brief rrc NGAP procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#include "rrc_gNB_NGAP.h" +#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "rrc_eNB_S1AP.h" +#include "gnb_config.h" +#include "common/ran_context.h" +#include "gtpv1u.h" + +#include "asn1_conversions.h" +#include "intertask_interface.h" +#include "pdcp.h" +#include "pdcp_primitives.h" + +#include "msc.h" + +#include "gtpv1u_eNB_task.h" +#include "gtpv1u_gNB_task.h" +#include "RRC/LTE/rrc_eNB_GTPV1U.h" +#include "RRC/NR/rrc_gNB_GTPV1U.h" + +#include "S1AP_NAS-PDU.h" +#include "executables/softmodem-common.h" +#include "UTIL/OSA/osa_defs.h" +#include "ngap_gNB_defs.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_management_procedures.h" +#include "NR_ULInformationTransfer.h" +#include "RRC/NR/MESSAGES/asn1_msg.h" +#include "NR_UERadioAccessCapabilityInformation.h" +#include "NR_UE-CapabilityRAT-ContainerList.h" + +extern RAN_CONTEXT_t RC; + +/* Value to indicate an invalid UE initial id */ +static const uint16_t UE_INITIAL_ID_INVALID = 0; + +/* Masks for NGAP Encryption algorithms, NEA0 is always supported (not coded) */ +static const uint16_t NGAP_ENCRYPTION_NEA1_MASK = 0x8000; +static const uint16_t NGAP_ENCRYPTION_NEA2_MASK = 0x4000; +static const uint16_t NGAP_ENCRYPTION_NEA3_MASK = 0x2000; + +/* Masks for NGAP Integrity algorithms, NIA0 is always supported (not coded) */ +static const uint16_t NGAP_INTEGRITY_NIA1_MASK = 0x8000; +static const uint16_t NGAP_INTEGRITY_NIA2_MASK = 0x4000; +static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000; + +#define INTEGRITY_ALGORITHM_NONE NR_IntegrityProtAlgorithm_nia0 + +/*! \fn uint16_t get_next_ue_initial_id(uint8_t mod_id) + *\brief provide an UE initial ID for NGAP initial communication. + *\param mod_id Instance ID of gNB. + *\return the UE initial ID. + */ +//------------------------------------------------------------------------------ +static uint16_t +get_next_ue_initial_id( + const module_id_t mod_id +) +//------------------------------------------------------------------------------ +{ + static uint16_t ue_initial_id[NUMBER_OF_gNB_MAX]; + ue_initial_id[mod_id]++; + + /* Never use UE_INITIAL_ID_INVALID this is the invalid id! */ + if (ue_initial_id[mod_id] == UE_INITIAL_ID_INVALID) { + ue_initial_id[mod_id]++; + } + + return ue_initial_id[mod_id]; +} + +//------------------------------------------------------------------------------ +/* +* Get the UE NG struct containing hashtables NG_id/UE_id. +* Is also used to set the NG_id of the UE, depending on inputs. +*/ +struct rrc_ue_ngap_ids_s * +rrc_gNB_NGAP_get_ue_ids( + gNB_RRC_INST *const rrc_instance_pP, + const uint16_t ue_initial_id, + const uint32_t gNB_ue_ngap_idP +) +//------------------------------------------------------------------------------ +{ + rrc_ue_ngap_ids_t *result = NULL; + rrc_ue_ngap_ids_t *result2 = NULL; + /*****************************/ + instance_t instance = 0; + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + rrc_gNB_ue_context_t *ue_context_p = NULL; + /*****************************/ + hashtable_rc_t h_rc; + + if (ue_initial_id != UE_INITIAL_ID_INVALID) { + h_rc = hashtable_get(rrc_instance_pP->initial_id2_ngap_ids, (hash_key_t)ue_initial_id, (void **)&result); + + if (h_rc == HASH_TABLE_OK) { + if (gNB_ue_ngap_idP > 0) { + h_rc = hashtable_get(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_idP, (void **)&result2); + + if (h_rc != HASH_TABLE_OK) { // this case is equivalent to associate gNB_ue_ngap_idP and ue_initial_id + result2 = malloc(sizeof(*result2)); + + if (NULL != result2) { + *result2 = *result; + result2->gNB_ue_ngap_id = gNB_ue_ngap_idP; + result->gNB_ue_ngap_id = gNB_ue_ngap_idP; + h_rc = hashtable_insert(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_idP, result2); + + if (h_rc != HASH_TABLE_OK) { + LOG_E(NGAP, "[gNB %ld] Error while hashtable_insert in ngap_id2_ngap_ids gNB_ue_ngap_idP %"PRIu32"\n", + rrc_instance_pP - RC.nrrrc[0], + gNB_ue_ngap_idP); + } + } + } else { // here we should check that the association was done correctly + if ((result->ue_initial_id != result2->ue_initial_id) || (result->gNB_ue_ngap_id != result2->gNB_ue_ngap_id)) { + LOG_E(NGAP, "[gNB %ld] Error while hashtable_get, two rrc_ue_ngap_ids_t that should be equal, are not:\n \ + ue_initial_id 1 = %"PRIu16",\n \ + ue_initial_id 2 = %"PRIu16",\n \ + gNB_ue_ngap_idP 1 = %"PRIu32",\n \ + gNB_ue_ngap_idP 2 = %"PRIu32"\n", + rrc_instance_pP - RC.nrrrc[0], + result->ue_initial_id, + result2->ue_initial_id, + result->gNB_ue_ngap_id, + result2->gNB_ue_ngap_id); + // Still return *result + } + } + } // end if if (gNB_ue_ngap_idP > 0) + } else { // end if (h_rc == HASH_TABLE_OK) + LOG_E(NGAP, "[gNB %ld] In hashtable_get, couldn't find in initial_id2_ngap_ids ue_initial_id %"PRIu16"\n", + rrc_instance_pP - RC.nrrrc[0], + ue_initial_id); + return NULL; + /* + * At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error. + * One could try to find the struct instance based on ngap_id2_ngap_ids and gNB_ue_ngap_idP (if > 0), + * but this behavior is not expected at the moment. + */ + } // end else (h_rc != HASH_TABLE_OK) + } else { // end if (ue_initial_id != UE_INITIAL_ID_INVALID) + if (gNB_ue_ngap_idP > 0) { + h_rc = hashtable_get(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_idP, (void **)&result); + + if (h_rc != HASH_TABLE_OK) { + /* + * This case is uncommon, but can happen when: + * -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist + * but is not associated with gNB_ue_ngap_id + * -> ... (?) + */ + LOG_E(NGAP, "[gNB %ld] In hashtable_get, couldn't find in ngap_id2_ngap_ids gNB_ue_ngap_idP %"PRIu32", trying to find it through NGAP context\n", + rrc_instance_pP - RC.nrrrc[0], + gNB_ue_ngap_idP); + instance = GNB_MODULE_ID_TO_INSTANCE(rrc_instance_pP - RC.nrrrc[0]); // get gNB instance + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); // get ngap_gNB_instance + + if (ngap_gNB_instance_p != NULL) { + ue_desc_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, gNB_ue_ngap_idP); // get s1ap_eNB_ue_context + } else { + LOG_E(NGAP, "[gNB instance %ld] Couldn't find the gNB NGAP context\n", + instance); + return NULL; + } + + if (ue_desc_p != NULL) { + struct ngap_gNB_ue_context_s *ngap_ue_context_p = NULL; + + if ((ngap_ue_context_p = RB_REMOVE(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_desc_p)) != NULL) { + LOG_E(NR_RRC, "Removed UE context gNB_ue_ngap_id %u\n", ngap_ue_context_p->gNB_ue_ngap_id); + ngap_gNB_free_ue_context(ngap_ue_context_p); + } else { + LOG_E(NR_RRC, "Removing UE context gNB_ue_ngap_id %u: did not find context\n",ue_desc_p->gNB_ue_ngap_id); + } + + return NULL; //skip the operation below to avoid loop + result = rrc_gNB_NGAP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, gNB_ue_ngap_idP); + + if (ue_desc_p->ue_initial_id != UE_INITIAL_ID_INVALID) { + result = rrc_gNB_NGAP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, gNB_ue_ngap_idP); + + if (result != NULL) { + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti); + + if ((ue_context_p != NULL) && (ue_context_p->ue_context.gNB_ue_ngap_id == 0)) { + ue_context_p->ue_context.gNB_ue_ngap_id = gNB_ue_ngap_idP; + } else { + LOG_E(NR_RRC, "[gNB %ld] Incoherence between RRC context and NGAP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", + rrc_instance_pP - RC.nrrrc[0], + (ue_context_p==NULL)?99999:ue_context_p->ue_context.gNB_ue_ngap_id, + gNB_ue_ngap_idP, + result->ue_rnti); + } + } + } else { + LOG_E(NGAP, "[gNB %ld] NGAP context found but ue_initial_id is invalid (0)\n", rrc_instance_pP - RC.nrrrc[0]); + return NULL; + } + } else { + LOG_E(NGAP, "[gNB %ld] In hashtable_get, couldn't find in ngap_id2_ngap_ids gNB_ue_ngap_idP %"PRIu32", because ue_initial_id is invalid in NGAP context\n", + rrc_instance_pP - RC.nrrrc[0], + gNB_ue_ngap_idP); + return NULL; + } + } // end if (h_rc != HASH_TABLE_OK) + } // end if (gNB_ue_ngap_idP > 0) + } // end else (ue_initial_id == UE_INITIAL_ID_INVALID) + + return result; +} + +//------------------------------------------------------------------------------ +static struct rrc_gNB_ue_context_s * +rrc_gNB_get_ue_context_from_ngap_ids( + const instance_t instanceP, + const uint16_t ue_initial_idP, + const uint32_t gNB_ue_ngap_idP +) +//------------------------------------------------------------------------------ +{ + rrc_ue_ngap_ids_t *temp = NULL; + temp = rrc_gNB_NGAP_get_ue_ids(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, gNB_ue_ngap_idP); + + if (temp != NULL) { + return rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instanceP)], temp->ue_rnti); + } + + return NULL; +} + +/*! \fn void process_gNB_security_key (const protocol_ctxt_t* const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, uint8_t *security_key) + *\brief save security key. + *\param ctxt_pP Running context. + *\param ue_context_pP UE context. + *\param security_key_pP The security key received from NGAP. + */ +//------------------------------------------------------------------------------ +void process_gNB_security_key ( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t *security_key_pP +) +//------------------------------------------------------------------------------ +{ + char ascii_buffer[65]; + uint8_t i; + /* Saves the security key */ + memcpy (ue_context_pP->ue_context.kgnb, security_key_pP, SECURITY_KEY_LENGTH); + memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH); + ue_context_pP->ue_context.nh_ncc = -1; + + for (i = 0; i < 32; i++) { + sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kgnb[i]); + } + + ascii_buffer[2 * i] = '\0'; + LOG_I(NR_RRC, "[gNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ascii_buffer); +} + +//------------------------------------------------------------------------------ +void +nr_rrc_pdcp_config_security( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const uint8_t send_security_mode_command +) +//------------------------------------------------------------------------------ +{ + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + (void)SRB_configList; + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + uint8_t *kUPenc = NULL; + pdcp_t *pdcp_p = NULL; + static int print_keys= 1; + hashtable_rc_t h_rc; + hash_key_t key; + +#ifndef PHYSIM + /* Derive the keys from kgnb */ + if (SRB_configList != NULL) { + nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kUPenc); + } + + nr_derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCenc); + nr_derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, + ue_context_pP->ue_context.kgnb, + &kRRCint); +#endif + if (!IS_SOFTMODEM_IQPLAYER) { + SET_LOG_DUMP(DEBUG_SECURITY) ; + } + + + if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { + if (print_keys == 1 ) { + print_keys =0; + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" ); + } + } + + key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); + + if (h_rc == HASH_TABLE_OK) { + pdcp_config_set_security( + ctxt_pP, + pdcp_p, + DCCH, + DCCH+2, + (send_security_mode_command == TRUE) ? + 0 | (ue_context_pP->ue_context.integrity_algorithm << 4) : + (ue_context_pP->ue_context.ciphering_algorithm ) | + (ue_context_pP->ue_context.integrity_algorithm << 4), + kRRCenc, + kRRCint, + kUPenc); + } else { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT"Could not get PDCP instance for SRB DCCH %u\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + } +} + +//------------------------------------------------------------------------------ +/* +* Initial UE NAS message on S1AP. +*/ +void +rrc_gNB_send_NGAP_NAS_FIRST_REQ( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + NR_RRCSetupComplete_IEs_t *rrcSetupComplete +) +//------------------------------------------------------------------------------ +{ + // gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; + MessageDef *message_p = NULL; + rrc_ue_ngap_ids_t *rrc_ue_ngap_ids_p = NULL; + hashtable_rc_t h_rc; + + message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_FIRST_REQ); + memset(&message_p->ittiMsg.ngap_nas_first_req, 0, sizeof(ngap_nas_first_req_t)); + ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); + NGAP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + rrc_ue_ngap_ids_p = malloc(sizeof(rrc_ue_ngap_ids_t)); + rrc_ue_ngap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + rrc_ue_ngap_ids_p->gNB_ue_ngap_id = UE_INITIAL_ID_INVALID; + rrc_ue_ngap_ids_p->ue_rnti = ctxt_pP->rnti; + + h_rc = hashtable_insert(RC.nrrrc[ctxt_pP->module_id]->initial_id2_ngap_ids, + (hash_key_t)ue_context_pP->ue_context.ue_initial_id, + rrc_ue_ngap_ids_p); + + if (h_rc != HASH_TABLE_OK) { + LOG_E(NGAP, "[gNB %d] Error while hashtable_insert in initial_id2_ngap_ids ue_initial_id %u\n", + ctxt_pP->module_id, + ue_context_pP->ue_context.ue_initial_id); + } + + /* Assume that cause is coded in the same way in RRC and NGap, just check that the value is in NGap range */ + AssertFatal(ue_context_pP->ue_context.establishment_cause < NGAP_RRC_CAUSE_LAST, + "Establishment cause invalid (%jd/%d) for gNB %d!", + ue_context_pP->ue_context.establishment_cause, + NGAP_RRC_CAUSE_LAST, + ctxt_pP->module_id); + NGAP_NAS_FIRST_REQ(message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause; + + /* Forward NAS message */ + NGAP_NAS_FIRST_REQ(message_p).nas_pdu.buffer = rrcSetupComplete->dedicatedNAS_Message.buf; + NGAP_NAS_FIRST_REQ(message_p).nas_pdu.length = rrcSetupComplete->dedicatedNAS_Message.size; + // extract_imsi(NGAP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, + // NGAP_NAS_FIRST_REQ (message_p).nas_pdu.length, + // ue_context_pP); + + /* Fill UE identities with available information */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask = NGAP_UE_IDENTITIES_NONE; + /* Fill s-TMSI */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.s_tmsi.m_tmsi = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi; + + /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ + int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; + NGAP_NAS_FIRST_REQ(message_p).selected_plmn_identity = selected_plmn_identity; + + if (rrcSetupComplete->registeredAMF != NULL) { + NR_RegisteredAMF_t *r_amf = rrcSetupComplete->registeredAMF; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.presenceMask |= NGAP_UE_IDENTITIES_guami; + + if (r_amf->plmn_Identity != NULL) { + if ((r_amf->plmn_Identity->mcc != NULL) && (r_amf->plmn_Identity->mcc->list.count > 0)) { + /* Use first indicated PLMN MCC if it is defined */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc = *r_amf->plmn_Identity->mcc->list.array[selected_plmn_identity]; + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", + ctxt_pP->module_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mcc, + ue_context_pP->ue_context.rnti); + } + + if (r_amf->plmn_Identity->mnc.list.count > 0) { + /* Use first indicated PLMN MNC if it is defined */ + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc = *r_amf->plmn_Identity->mnc.list.array[selected_plmn_identity]; + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", + ctxt_pP->module_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.mnc, + ue_context_pP->ue_context.rnti); + } + } else { + /* TODO */ + } + + /* amf_Identifier */ + uint32_t amf_Id = BIT_STRING_to_uint32(&r_amf->amf_Identifier); + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id = amf_Id >> 16; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id; + NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer = ue_context_pP->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer; + + ue_context_pP->ue_context.ue_guami.mcc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mcc; + ue_context_pP->ue_context.ue_guami.mnc = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc; + ue_context_pP->ue_context.ue_guami.mnc_len = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.mnc_len; + ue_context_pP->ue_context.ue_guami.amf_region_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_region_id; + ue_context_pP->ue_context.ue_guami.amf_set_id = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_set_id; + ue_context_pP->ue_context.ue_guami.amf_pointer = NGAP_NAS_FIRST_REQ(message_p).ue_identity.guami.amf_pointer; + + MSC_LOG_TX_MESSAGE(MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)&message_p->ittiMsg.ngap_nas_first_req, + sizeof(ngap_nas_first_req_t), + MSC_AS_TIME_FMT" NGAP_NAS_FIRST_REQ gNB %u UE %x", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->module_id, + ctxt_pP->rnti); + LOG_I(NGAP, "[gNB %d] Build NGAP_NAS_FIRST_REQ adding in s_TMSI: GUAMI amf_set_id %u amf_region_id %u ue %x\n", + ctxt_pP->module_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_set_id, + NGAP_NAS_FIRST_REQ (message_p).ue_identity.guami.amf_region_id, + ue_context_pP->ue_context.rnti); + } + + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, message_p); +} + +//------------------------------------------------------------------------------ +int +rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +) +//------------------------------------------------------------------------------ +{ + uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; + rrc_gNB_ue_context_t *ue_context_p = NULL; + protocol_ctxt_t ctxt; + uint8_t pdu_sessions_done = 0; + + ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id; + gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id; + + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); + LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n", + instance, msg_name, ue_initial_id, gNB_ue_ngap_id); + + if (ue_context_p == NULL) { + /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ + MessageDef *msg_fail_p = NULL; + LOG_W(NR_RRC, "[gNB %ld] In NGAP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_INITIAL_CONTEXT_SETUP_FAIL); + NGAP_INITIAL_CONTEXT_SETUP_FAIL (msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + // TODO add failure cause when defined! + itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); + return (-1); + } else { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id; + ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id; + ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag; + + if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions != 0) { + ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions; + for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { + if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) + continue; + ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW; + ue_context_p->ue_context.pdusession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done]; + pdu_sessions_done++; + + // TODO establish PDU SESSION + + if(pdu_sessions_done >= NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions) { + break; + } + } + } + + /* NAS PDU */ + ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag; + if (ue_context_p->ue_context.nas_pdu_flag == 1) { + ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length; + ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer; + } + + /* security */ + rrc_gNB_process_security(&ctxt, ue_context_p, &(NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_capabilities)); + process_gNB_security_key ( + &ctxt, + ue_context_p, + NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); + + uint8_t send_security_mode_command = TRUE; + + nr_rrc_pdcp_config_security( + &ctxt, + ue_context_p, + send_security_mode_command); + + if (send_security_mode_command) { + rrc_gNB_generate_SecurityModeCommand (&ctxt, ue_context_p); + send_security_mode_command = FALSE; + + nr_rrc_pdcp_config_security( + &ctxt, + ue_context_p, + send_security_mode_command); + } else { + /* rrc_gNB_generate_UECapabilityEnquiry */ + rrc_gNB_generate_UECapabilityEnquiry(&ctxt, ue_context_p); + } + + // in case, send the S1SP initial context response if it is not sent with the attach complete message + if (ue_context_p->ue_context.Status == NR_RRC_RECONFIGURED) { + LOG_I(NR_RRC, "Sending rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause); + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(&ctxt,ue_context_p); + } + + return 0; + } +} + +//------------------------------------------------------------------------------ +void +rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +) +//------------------------------------------------------------------------------ +{ + MessageDef *msg_p = NULL; + int pdusession; + int e_rabs_done = 0; + int e_rabs_failed = 0; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP); + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + + for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) { + if (ue_context_pP->ue_context.pdusession[pdusession].status == E_RAB_STATUS_DONE) { + e_rabs_done++; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + // TODO add other information from S1-U when it will be integrated + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession]; + memcpy(NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.buffer , ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, 20); + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.length = 4; + ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_ESTABLISHED; + } else { + e_rabs_failed++; + ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_FAILED; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + // TODO add cause when it will be integrated + } + } + + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_S1AP_ENB, + (const char *)&NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p), + sizeof(ngap_initial_context_setup_resp_t), + MSC_AS_TIME_FMT" INITIAL_CONTEXT_SETUP_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id, + e_rabs_done, e_rabs_failed); + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = e_rabs_done; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = e_rabs_failed; + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); +} + +static NR_CipheringAlgorithm_t rrc_gNB_select_ciphering(uint16_t algorithms) { + if (algorithms & NGAP_ENCRYPTION_NEA3_MASK) { + return NR_CipheringAlgorithm_nea3; + } + + if (algorithms & NGAP_ENCRYPTION_NEA2_MASK) { + return NR_CipheringAlgorithm_nea2; + } + + if (algorithms & NGAP_ENCRYPTION_NEA1_MASK) { + return NR_CipheringAlgorithm_nea1; + } + + return NR_CipheringAlgorithm_nea0; +} + +static e_NR_IntegrityProtAlgorithm rrc_gNB_select_integrity(uint16_t algorithms) { + if (algorithms & NGAP_INTEGRITY_NIA3_MASK) { + return NR_IntegrityProtAlgorithm_nia3; + } + + if (algorithms & NGAP_INTEGRITY_NIA2_MASK) { + return NR_IntegrityProtAlgorithm_nia2; + } + + if (algorithms & NGAP_INTEGRITY_NIA1_MASK) { + return NR_IntegrityProtAlgorithm_nia1; + } + + return NR_IntegrityProtAlgorithm_nia0; +} + +int +rrc_gNB_process_security( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + ngap_security_capabilities_t *security_capabilities_pP +) { + boolean_t changed = FALSE; + NR_CipheringAlgorithm_t cipheringAlgorithm; + e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; + /* Save security parameters */ + ue_context_pP->ue_context.security_capabilities = *security_capabilities_pP; + // translation + LOG_D(NR_RRC, + "[gNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n", + ctxt_pP->module_id, + ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms, + (unsigned long)ue_context_pP->ue_context.ciphering_algorithm, + ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms, + ue_context_pP->ue_context.integrity_algorithm); + /* Select relevant algorithms */ + cipheringAlgorithm = rrc_gNB_select_ciphering (ue_context_pP->ue_context.security_capabilities.nRencryption_algorithms); + + if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) { + ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm; + changed = TRUE; + } + + integrityProtAlgorithm = rrc_gNB_select_integrity (ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms); + + if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) { + ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm; + changed = TRUE; + } + + LOG_I (NR_RRC, "[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", + ctxt_pP->module_id, + ue_context_pP->ue_context.rnti, + security_capabilities_pP, + (unsigned long)cipheringAlgorithm, + integrityProtAlgorithm, + changed ? "changed" : "same"); + return changed; +} + +//------------------------------------------------------------------------------ +int +rrc_gNB_process_NGAP_DOWNLINK_NAS( + MessageDef *msg_p, + const char *msg_name, + instance_t instance, + mui_t *rrc_gNB_mui +) +//------------------------------------------------------------------------------ +{ + uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; + uint32_t length; + uint8_t *buffer; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + protocol_ctxt_t ctxt; + memset(&ctxt, 0, sizeof(protocol_ctxt_t)); + ue_initial_id = NGAP_DOWNLINK_NAS (msg_p).ue_initial_id; + gNB_ue_ngap_id = NGAP_DOWNLINK_NAS (msg_p).gNB_ue_ngap_id; + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); + LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u\n", + instance, + msg_name, + ue_initial_id, + gNB_ue_ngap_id); + + if (ue_context_p == NULL) { + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_NGAP_GNB, + NULL, + 0, + MSC_AS_TIME_FMT" DOWNLINK-NAS UE initial id %u gNB_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_initial_id, + gNB_ue_ngap_id); + /* Can not associate this message to an UE index, send a failure to NGAP and discard it! */ + MessageDef *msg_fail_p; + LOG_W(NR_RRC, "[gNB %ld] In NGAP_DOWNLINK_NAS: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); + msg_fail_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_NAS_NON_DELIVERY_IND); + NGAP_NAS_NON_DELIVERY_IND (msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + NGAP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.length = NGAP_DOWNLINK_NAS (msg_p).nas_pdu.length; + NGAP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.buffer = NGAP_DOWNLINK_NAS (msg_p).nas_pdu.buffer; + // TODO add failure cause when defined! + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_NGAP_GNB, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" NGAP_NAS_NON_DELIVERY_IND UE initial id %u gNB_ue_ngap_id %u (ue ctxt !found)", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_initial_id, + gNB_ue_ngap_id); + itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); + return (-1); + } else { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + + /* Is it the first income from NGAP ? */ + if (ue_context_p->ue_context.gNB_ue_ngap_id == 0) { + ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_DOWNLINK_NAS (msg_p).gNB_ue_ngap_id; + } + + MSC_LOG_RX_MESSAGE( + MSC_RRC_GNB, + MSC_NGAP_GNB, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" DOWNLINK-NAS UE initial id %u gNB_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_initial_id, + NGAP_DOWNLINK_NAS (msg_p).gNB_ue_ngap_id); + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_NR_DLInformationTransfer ( + instance, + &buffer, + rrc_gNB_get_next_transaction_identifier (instance), + NGAP_DOWNLINK_NAS (msg_p).nas_pdu.length, + NGAP_DOWNLINK_NAS (msg_p).nas_pdu.buffer); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, buffer, length, "[MSG] RRC DL Information Transfer\n"); + /* + * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. + */ +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, length); + memcpy (message_buffer, buffer, length); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = length; + itti_send_msg_to_task (TASK_RRC_UE_SIM, instance, message_p); + LOG_I(NR_RRC, "Send DL NAS message \n"); +#else + /* Transfer data to PDCP */ + nr_rrc_data_req ( + &ctxt, + ue_context_p->ue_context.Srb2.Srb_info.Srb_id, + (*rrc_gNB_mui)++, + SDU_CONFIRM_NO, + length, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif + return (0); + } +} + +//------------------------------------------------------------------------------ +void +rrc_gNB_send_NGAP_UPLINK_NAS( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + NR_UL_DCCH_Message_t *const ul_dcch_msg +) +//------------------------------------------------------------------------------ +{ + uint32_t pdu_length; + uint8_t *pdu_buffer; + MessageDef *msg_p; + NR_ULInformationTransfer_t *ulInformationTransfer = ul_dcch_msg->message.choice.c1->choice.ulInformationTransfer; + + if (ulInformationTransfer->criticalExtensions.present == NR_ULInformationTransfer__criticalExtensions_PR_ulInformationTransfer) { + pdu_length = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->size; + pdu_buffer = ulInformationTransfer->criticalExtensions.choice.ulInformationTransfer->dedicatedNAS_Message->buf; + msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UPLINK_NAS); + NGAP_UPLINK_NAS (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + NGAP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; + NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; + // extract_imsi(NGAP_UPLINK_NAS (msg_p).nas_pdu.buffer, + // NGAP_UPLINK_NAS (msg_p).nas_pdu.length, + // ue_context_pP); + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); + LOG_I(NR_RRC,"Send RRC GNB UL Information Transfer \n"); + } +} + +//------------------------------------------------------------------------------ +void +rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t xid +) +//------------------------------------------------------------------------------ +{ + MessageDef *msg_p; + int pdu_sessions_done = 0; + int pdu_sessions_failed = 0; + int pdusession; + int qos_flow_index; + + msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_RESP); + NGAP_PDUSESSION_SETUP_RESP(msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + + for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) { + // if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) { + if (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_DONE) { + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + // NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = 1; + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pdusession[pdusession].param.nb_qos; + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession]; + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.pdu_session_type = PDUSessionType_ipv4; + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.length = ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].length; + memcpy(NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.buffer, + ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, sizeof(uint8_t)*20); + for (qos_flow_index = 0; qos_flow_index < NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow; qos_flow_index++) { + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = + ue_context_pP->ue_context.pdusession[pdusession].param.qos[qos_flow_index].qfi; + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; + } + + ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED; + LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d, pdusession_id %d, teid: %u, addr: %d.%d.%d.%d \n ", + pdu_sessions_done, pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid, + ue_context_pP->ue_context.nb_of_pdusessions, + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].pdusession_id, + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gtp_teid, + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[0], + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[1], + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[2], + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[3]); + pdu_sessions_done++; + } else if ((ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_NEW) || + (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) { + LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n"); + } else { /* to be improved */ + ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_FAILED; + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + pdu_sessions_failed++; + // TODO add cause when it will be integrated + } + NGAP_PDUSESSION_SETUP_RESP(msg_p).nb_of_pdusessions = pdu_sessions_done; + NGAP_PDUSESSION_SETUP_RESP(msg_p).nb_of_pdusessions_failed = pdu_sessions_failed; + // } else { + // LOG_D(NR_RRC,"xid does not corresponds (context pdu_sessions index %d, status %d, xid %d/%d) \n ", + // pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid, ue_context_pP->ue_context.pdusession[pdusession].xid); + // } + } + + if ((pdu_sessions_done > 0) ) { + LOG_I(NR_RRC,"NGAP_PDUSESSION_SETUP_RESP: sending the message: nb_of_pdusessions %d, total pdu_sessions %d, index %d\n", + ue_context_pP->ue_context.nb_of_pdusessions, ue_context_pP->ue_context.setup_pdu_sessions, pdusession); + MSC_LOG_TX_MESSAGE( + MSC_RRC_GNB, + MSC_NGAP_GNB, + (const char *)&NGAP_PDUSESSION_SETUP_RESP (msg_p), + sizeof(ngap_pdusession_setup_resp_t), + MSC_AS_TIME_FMT" PDUSESSION_SETUP_RESP UE %X gNB_ue_ngap_id %u pdu_sessions:%u succ %u fail", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + NGAP_PDUSESSION_SETUP_RESP (msg_p).gNB_ue_ngap_id, + pdu_sessions_done, pdu_sessions_failed); + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); + } + + for(int i = 0; i < NB_RB_MAX; i++) { + ue_context_pP->ue_context.pdusession[i].xid = -1; + } + + return; +} + +//------------------------------------------------------------------------------ +int +rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +) +//------------------------------------------------------------------------------ +{ + uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; + rrc_gNB_ue_context_t *ue_context_p = NULL; + protocol_ctxt_t ctxt; + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; + uint8_t pdu_sessions_done; + uint8_t inde_list[NR_NB_RB_MAX - 3]= {0}; + int ret = 0; + + ue_initial_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).ue_initial_id; + gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, gNB_ue_ngap_id); + LOG_I(NR_RRC, "[gNB %ld] Received %s: ue_initial_id %d, gNB_ue_ngap_id %u \n", + instance, msg_name, ue_initial_id, gNB_ue_ngap_id); + + if (ue_context_p == NULL) { + MessageDef *msg_fail_p = NULL; + LOG_W(NR_RRC, "[gNB %ld] In NGAP_PDUSESSION_SETUP_REQ: unknown UE from NGAP ids (%d, %u)\n", instance, ue_initial_id, gNB_ue_ngap_id); + msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_PDUSESSION_SETUP_REQUEST_FAIL); + NGAP_PDUSESSION_SETUP_REQ(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + // TODO add failure cause when defined! + itti_send_msg_to_task (TASK_NGAP, instance, msg_fail_p); + return (-1); + } else { + memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; + pdu_sessions_done = 0; + + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { + if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) + continue; + ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW; + ue_context_p->ue_context.pdusession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; + create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; + create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; + memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer, + NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer, + sizeof(uint8_t)*20); + create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.length; + LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n", + i, + create_tunnel_req.upf_NGu_teid[i], + create_tunnel_req.pdusession_id[i]); + inde_list[pdu_sessions_done] = i; + pdu_sessions_done++; + + if(pdu_sessions_done >= nb_pdusessions_tosetup) { + break; + } + } + + ue_context_p->ue_context.nb_of_pdusessions = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; + ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).gNB_ue_ngap_id; + ue_context_p->ue_context.amf_ue_ngap_id = NGAP_PDUSESSION_SETUP_REQ(msg_p).amf_ue_ngap_id; + create_tunnel_req.rnti = ue_context_p->ue_context.rnti; + create_tunnel_req.num_tunnels = pdu_sessions_done; + + ret = gtpv1u_create_ngu_tunnel( + instance, + &create_tunnel_req, + &create_tunnel_resp); + if (ret != 0) { + LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_ng = 1; + ue_context_p->ue_context.ue_release_timer_thres_ng = 100; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ul_failure_timer = 20000; // set ul_failure to 20000 for triggering rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ + // rrc_gNB_free_UE(ctxt.module_id,ue_context_p); + ue_context_p->ue_context.ul_failure_timer = 0; + return (0); + } + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + &ctxt, + &create_tunnel_resp, + &inde_list[0]); + ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup; + + // TEST + ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE; + rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0); + return(0); + } +} + +void +rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( + const module_id_t gnb_mod_idP, + const rrc_gNB_ue_context_t *const ue_context_pP, + const ngap_Cause_t causeP, + const long cause_valueP) +//------------------------------------------------------------------------------ +{ + if (ue_context_pP == NULL) { + LOG_E(RRC, "[gNB] In NGAP_UE_CONTEXT_RELEASE_REQ: invalid UE\n"); + } else { + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_NGAP_GNB, + NULL, + 0, + "0 NGAP_UE_CONTEXT_RELEASE_REQ gNB_ue_ngap_id 0x%06"PRIX32" ", + ue_context_pP->ue_context.gNB_ue_ngap_id); + MessageDef *msg_context_release_req_p = NULL; + msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_REQ); + NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause = causeP; + NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP; + NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).nb_of_pdusessions = ue_context_pP->ue_context.setup_pdu_sessions; + for (int pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) { + NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + } + itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg_context_release_req_p); + } +} +/*------------------------------------------------------------------------------*/ +int +rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance) +{ + uint32_t gNB_ue_ngap_id; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_REQ(msg_p).gNB_ue_ngap_id; + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); + + if (ue_context_p == NULL) { + /* Can not associate this message to an UE index, send a failure to ngAP and discard it! */ + MessageDef *msg_fail_p; + LOG_W(RRC, "[gNB %ld] In NGAP_UE_CONTEXT_RELEASE_REQ: unknown UE from gNB_ue_ngap_id (%u)\n", + instance, + gNB_ue_ngap_id); + msg_fail_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */ + NGAP_UE_CONTEXT_RELEASE_RESP(msg_fail_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + // TODO add failure cause when defined! + itti_send_msg_to_task(TASK_NGAP, instance, msg_fail_p); + return (-1); + } else { + /* TODO release context. */ + /* Send the response */ + { + MessageDef *msg_resp_p; + msg_resp_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_RESP); + NGAP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_NGAP, instance, msg_resp_p); + } + return (0); + } +} + +//----------------------------------------------------------------------------- +/* +* Process the NG command NGAP_UE_CONTEXT_RELEASE_COMMAND, sent by AMF. +* The gNB should remove all pdu session, NG context, and other context of the UE. +*/ +int +rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( + MessageDef *msg_p, + const char *msg_name, + instance_t instance) { + //----------------------------------------------------------------------------- + uint32_t gNB_ue_ngap_id = 0; + protocol_ctxt_t ctxt; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + struct rrc_ue_ngap_ids_s *rrc_ue_ngap_ids = NULL; + gNB_ue_ngap_id = NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id; + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); + + if (ue_context_p == NULL) { + /* Can not associate this message to an UE index */ + MessageDef *msg_complete_p = NULL; + LOG_W(NR_RRC, "[gNB %ld] In NGAP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from gNB_ue_ngap_id (%u)\n", + instance, + gNB_ue_ngap_id); + MSC_LOG_EVENT(MSC_RRC_GNB, "0 NGAP_UE_CONTEXT_RELEASE_COMPLETE gNB_ue_ngap_id 0x%06"PRIX32" context not found", + gNB_ue_ngap_id); + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, + MSC_NGAP_GNB, + NULL, + 0, + "0 NGAP_UE_CONTEXT_RELEASE_COMPLETE gNB_ue_ngap_id 0x%06"PRIX32" ", + gNB_ue_ngap_id); + msg_complete_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); + NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).gNB_ue_ngap_id = gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_NGAP, instance, msg_complete_p); + rrc_ue_ngap_ids = rrc_gNB_NGAP_get_ue_ids(RC.nrrrc[instance], UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); + + if (rrc_ue_ngap_ids != NULL) { + rrc_gNB_NGAP_remove_ue_ids(RC.nrrrc[instance], rrc_ue_ngap_ids); + } + + return -1; + } else { + ue_context_p->ue_context.ue_release_timer_ng = 0; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); + return 0; + } +} +//------------------------------------------------------------------------------ +/* +* Remove UE ids (ue_initial_id and ng_id) from hashtables. +*/ +void +rrc_gNB_NGAP_remove_ue_ids( + gNB_RRC_INST *const rrc_instance_pP, + struct rrc_ue_ngap_ids_s *const ue_ids_pP +) +//------------------------------------------------------------------------------ +{ + hashtable_rc_t h_rc; + + if (rrc_instance_pP == NULL) { + LOG_E(NR_RRC, "Bad NR RRC instance\n"); + return; + } + + if (ue_ids_pP == NULL) { + LOG_E(NR_RRC, "Trying to free a NULL NGAP UE IDs\n"); + return; + } + + const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id; + const uint32_t gNB_ue_ngap_id = ue_ids_pP->gNB_ue_ngap_id; + + if (gNB_ue_ngap_id > 0) { + h_rc = hashtable_remove(rrc_instance_pP->ngap_id2_ngap_ids, (hash_key_t)gNB_ue_ngap_id); + + if (h_rc != HASH_TABLE_OK) { + LOG_W(NR_RRC, "NGAP Did not find entry in hashtable ngap_id2_ngap_ids for gNB_ue_ngap_id %u\n", gNB_ue_ngap_id); + } else { + LOG_W(NR_RRC, "NGAP removed entry in hashtable ngap_id2_ngap_ids for gNB_ue_ngap_id %u\n", gNB_ue_ngap_id); + } + } + + if (ue_initial_id != UE_INITIAL_ID_INVALID) { + h_rc = hashtable_remove(rrc_instance_pP->initial_id2_ngap_ids, (hash_key_t)ue_initial_id); + + if (h_rc != HASH_TABLE_OK) { + LOG_W(NR_RRC, "NGAP Did not find entry in hashtable initial_id2_ngap_ids for ue_initial_id %u\n", ue_initial_id); + } else { + LOG_W(NR_RRC, "NGAP removed entry in hashtable initial_id2_ngap_ids for ue_initial_id %u\n", ue_initial_id); + } + } +} +void +rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + NR_UL_DCCH_Message_t *const ul_dcch_msg +) +//------------------------------------------------------------------------------ +{ + NR_UE_CapabilityRAT_ContainerList_t *ueCapabilityRATContainerList = ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + /* 4096 is arbitrary, should be big enough */ + unsigned char buf[4096]; + unsigned char *buf2; + NR_UERadioAccessCapabilityInformation_t rac; + + if (ueCapabilityRATContainerList->list.count == 0) { + LOG_W(RRC, "[gNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti); + } + + asn_enc_rval_t ret = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, NULL, ueCapabilityRATContainerList, buf, 4096); + + if (ret.encoded == -1) abort(); + + memset(&rac, 0, sizeof(NR_UERadioAccessCapabilityInformation_t)); + rac.criticalExtensions.present = NR_UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; + rac.criticalExtensions.choice.c1 = calloc(1,sizeof(*rac.criticalExtensions.choice.c1)); + rac.criticalExtensions.choice.c1->present = NR_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation; + rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation = calloc(1,sizeof(NR_UERadioAccessCapabilityInformation_IEs_t)); + rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->ue_RadioAccessCapabilityInfo.buf = buf; + rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->ue_RadioAccessCapabilityInfo.size = (ret.encoded+7)/8; + rac.criticalExtensions.choice.c1->choice.ueRadioAccessCapabilityInformation->nonCriticalExtension = NULL; + /* 8192 is arbitrary, should be big enough */ + buf2 = malloc16(8192); + + if (buf2 == NULL) abort(); + + ret = uper_encode_to_buffer(&asn_DEF_NR_UERadioAccessCapabilityInformation, NULL, &rac, buf2, 8192); + + if (ret.encoded == -1) abort(); + + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_UE_CAPABILITIES_IND); + NGAP_UE_CAPABILITIES_IND (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + NGAP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = (ret.encoded+7)/8; + NGAP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = buf2; + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); + LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n"); +} + +//------------------------------------------------------------------------------ +void +rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t xid +) +//------------------------------------------------------------------------------ +{ + int pdu_sessions_released = 0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_RELEASE_RESPONSE); + NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; + + for (int i = 0; i < NB_RB_MAX; i++) { + if (xid == ue_context_pP->ue_context.pdusession[i].xid) { + NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id = + ue_context_pP->ue_context.pdusession[i].param.pdusession_id; + pdu_sessions_released++; + //clear + memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t)); + } + } + + NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_released = pdu_sessions_released; + NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).nb_of_pdusessions_failed = ue_context_pP->ue_context.nb_release_of_pdusessions; + memcpy(&(NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusessions_failed[0]), &ue_context_pP->ue_context.pdusessions_release_failed[0], + sizeof(pdusession_failed_t)*ue_context_pP->ue_context.nb_release_of_pdusessions); + ue_context_pP->ue_context.setup_pdu_sessions -= pdu_sessions_released; + LOG_I(NR_RRC,"NGAP PDUSESSION RELEASE RESPONSE: GNB_UE_NGAP_ID %u release_pdu_sessions %d setup_pdu_sessions %d \n", + NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id, + pdu_sessions_released, ue_context_pP->ue_context.setup_pdu_sessions); + itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); + + //clear xid + for(int i = 0; i < NB_RB_MAX; i++) { + ue_context_pP->ue_context.pdusession[i].xid = -1; + } + + //clear release pdusessions + ue_context_pP->ue_context.nb_release_of_pdusessions = 0; + memset(&ue_context_pP->ue_context.pdusessions_release_failed[0], 0, sizeof(pdusession_failed_t)*NGAP_MAX_PDUSESSION); +} + +//------------------------------------------------------------------------------ +int +rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +) +//------------------------------------------------------------------------------ +{ + uint32_t gNB_ue_ngap_id; + rrc_gNB_ue_context_t *ue_context_p = NULL; + protocol_ctxt_t ctxt; + pdusession_release_t pdusession_release_params[NGAP_MAX_PDUSESSION]; + uint8_t nb_pdusessions_torelease; + MessageDef *msg_delete_tunnels_p = NULL; + uint8_t xid; + int i, pdusession; + uint8_t b_existed,is_existed; + uint8_t pdusession_release_drb = 0; + + memcpy(&pdusession_release_params[0], &(NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).pdusession_release_params[0]), + sizeof(pdusession_release_t)*NGAP_MAX_PDUSESSION); + gNB_ue_ngap_id = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id; + nb_pdusessions_torelease = NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).nb_pdusessions_torelease; + if (nb_pdusessions_torelease > NGAP_MAX_PDUSESSION) { + return -1; + } + ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, UE_INITIAL_ID_INVALID, gNB_ue_ngap_id); + LOG_I(NR_RRC, "[gNB %ld] Received %s: gNB_ue_ngap_id %u \n", instance, msg_name, gNB_ue_ngap_id); + + if (ue_context_p != NULL) { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + xid = rrc_gNB_get_next_transaction_identifier(ctxt.module_id); + LOG_I(NR_RRC,"PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u release_pdusessions %d \n", + NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, gNB_ue_ngap_id, nb_pdusessions_torelease); + + for (pdusession = 0; pdusession < nb_pdusessions_torelease; pdusession++) { + b_existed = 0; + is_existed = 0; + + for (i = pdusession-1; i >= 0; i--) { + if (pdusession_release_params[pdusession].pdusession_id == pdusession_release_params[i].pdusession_id) { + is_existed = 1; + break; + } + } + + if(is_existed == 1) { + // pdusession_id is existed + continue; + } + + for (i = 0; i < NR_NB_RB_MAX; i++) { + if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) { + b_existed = 1; + break; + } + } + + if(b_existed == 0) { + // no pdusession_id + LOG_I(NR_RRC, "no pdusession_id \n"); + ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id; + ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; + ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30; + ue_context_p->ue_context.nb_release_of_pdusessions++; + } else { + if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) { + ue_context_p->ue_context.pdusession[i].xid = xid; + continue; + } else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) { + LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id); + ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE; + ue_context_p->ue_context.pdusession[i].xid = xid; + pdusession_release_drb++; + } else { + // pdusession_id status NG + ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].pdusession_id = pdusession_release_params[pdusession].pdusession_id; + ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause = NGAP_CAUSE_RADIO_NETWORK; + ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 0; + ue_context_p->ue_context.nb_release_of_pdusessions++; + } + } + } + + if(pdusession_release_drb > 0) { + //TODO RRCReconfiguration To UE + LOG_I(NR_RRC, "Send RRCReconfiguration To UE \n"); + rrc_gNB_generate_dedicatedRRCReconfiguration_release(&ctxt, ue_context_p, xid, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.length, NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).nas_pdu.buffer); + } else { + //gtp tunnel delete + LOG_I(NR_RRC, "gtp tunnel delete \n"); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, 0, GTPV1U_GNB_DELETE_TUNNEL_REQ); + memset(>PV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for(i = 0; i < NB_RB_MAX; i++) { + if(xid == ue_context_p->ue_context.pdusession[i].xid) { + GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i]; + ue_context_p->ue_context.gnb_gtp_teid[i] = 0; + memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i])); + ue_context_p->ue_context.gnb_gtp_psi[i] = 0; + } + } + + itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p); + //NGAP_PDUSESSION_RELEASE_RESPONSE + rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); + LOG_I(NR_RRC, "Send PDU Session Release Response \n"); + } + } else { + LOG_E(NR_RRC, "PDU Session Release Command: AMF_UE_NGAP_ID %lu GNB_UE_NGAP_ID %u Error ue_context_p NULL \n", + NGAP_PDUSESSION_RELEASE_COMMAND (msg_p).amf_ue_ngap_id&0x000000FFFFFFFFFF, NGAP_PDUSESSION_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id); + return -1; + } + + return 0; +} + +void nr_rrc_rx_tx(void) { + // check timers + + // check if UEs are lost, to remove them from upper layers + + // + +} + diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h new file mode 100644 index 0000000000..f13c468f94 --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -0,0 +1,166 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file rrc_gNB_NGAP.h + * \brief rrc NGAP procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#ifndef RRC_GNB_NGAP_H_ +#define RRC_GNB_NGAP_H_ + +#include "rrc_gNB_UE_context.h" +#include "nr_rrc_defs.h" +#include "nr_rrc_extern.h" + +#include "NR_RRCSetupComplete-IEs.h" +#include "NR_RegisteredAMF.h" +#include "NR_UL-DCCH-Message.h" + +typedef struct rrc_ue_ngap_ids_s { + /* Tree related data */ + RB_ENTRY(rrc_ue_ngap_ids_s) entries; + + // keys + uint16_t ue_initial_id; + uint32_t gNB_ue_ngap_id; + + // value + rnti_t ue_rnti; +} rrc_ue_ngap_ids_t; + +void +rrc_gNB_send_NGAP_NAS_FIRST_REQ( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + NR_RRCSetupComplete_IEs_t *rrcSetupComplete +); + +int +rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +); + +void +rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP +); + +int +rrc_gNB_process_security( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + ngap_security_capabilities_t *security_capabilities_pP +); + +int +rrc_gNB_process_NGAP_DOWNLINK_NAS( + MessageDef *msg_p, + const char *msg_name, + instance_t instance, + mui_t *rrc_gNB_mui +); + +void +rrc_gNB_send_NGAP_UPLINK_NAS( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + NR_UL_DCCH_Message_t *const ul_dcch_msg +); + +void +rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t xid +); + +int +rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +); + +void +rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( + const module_id_t gnb_mod_idP, + const rrc_gNB_ue_context_t *const ue_context_pP, + const ngap_Cause_t causeP, + const long cause_valueP +); + +int +rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +); + +int +rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +); + +void +rrc_gNB_NGAP_remove_ue_ids( + gNB_RRC_INST *const rrc_instance_pP, + struct rrc_ue_ngap_ids_s *const ue_ids_pP +); + +void +rrc_gNB_send_NGAP_UE_CAPABILITIES_IND( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + NR_UL_DCCH_Message_t *const ul_dcch_msg +); + +int +rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( + MessageDef *msg_p, + const char *msg_name, + instance_t instance +); + +void +rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t xid +); + +void +nr_rrc_pdcp_config_security( + const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *const ue_context_pP, + const uint8_t send_security_mode_command +); + +#endif diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index b5fb50f509..988db09cc1 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -135,6 +135,7 @@ rrc_gNB_allocate_new_UE_context( for(int i = 0; i < NB_RB_MAX; i++) { new_p->ue_context.e_rab[i].xid = -1; + new_p->ue_context.pdusession[i].xid = -1; new_p->ue_context.modify_e_rab[i].xid = -1; } @@ -189,7 +190,7 @@ void rrc_gNB_free_mem_UE_context( //------------------------------------------------------------------------------ void rrc_gNB_remove_ue_context( - const protocol_ctxt_t *const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, gNB_RRC_INST *rrc_instance_pP, struct rrc_gNB_ue_context_s *ue_context_pP) //------------------------------------------------------------------------------ @@ -220,4 +221,82 @@ void rrc_gNB_remove_ue_context( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); } +//----------------------------------------------------------------------------- +// return the ue context if there is already an UE with ue_identityP, NULL otherwise +struct rrc_gNB_ue_context_s * +rrc_gNB_ue_context_random_exist( + gNB_RRC_INST *rrc_instance_pP, + const uint64_t ue_identityP +) +//----------------------------------------------------------------------------- +{ + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) { + if (ue_context_p->ue_context.random_ue_identity == ue_identityP) + return ue_context_p; + } + return NULL; +} +//----------------------------------------------------------------------------- +// return the ue context if there is already an UE with the same S-TMSI, NULL otherwise +struct rrc_gNB_ue_context_s * +rrc_gNB_ue_context_5g_s_tmsi_exist( + gNB_RRC_INST *rrc_instance_pP, + const uint64_t s_TMSI +) +//----------------------------------------------------------------------------- +{ + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head) { + LOG_I(NR_RRC,"checking for UE 5G S-TMSI %ld: rnti %d \n", + s_TMSI, ue_context_p->ue_context.rnti); + + if (ue_context_p->ue_context.ng_5G_S_TMSI_Part1 == s_TMSI) { + return ue_context_p; + } + } + return NULL; +} + +//----------------------------------------------------------------------------- +// return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection +struct rrc_gNB_ue_context_s * +rrc_gNB_get_next_free_ue_context( + const protocol_ctxt_t *const ctxt_pP, + gNB_RRC_INST *rrc_instance_pP, + const uint64_t ue_identityP +) +//----------------------------------------------------------------------------- +{ + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, ctxt_pP->rnti); + + if (ue_context_p == NULL) { + ue_context_p = rrc_gNB_allocate_new_UE_context(rrc_instance_pP); + + if (ue_context_p == NULL) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, no memory\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + return NULL; + } + + ue_context_p->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else + ue_context_p->ue_context.rnti = ctxt_pP->rnti; // yes duplicate, 1 may be removed + ue_context_p->ue_context.random_ue_identity = ue_identityP; + RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p); + LOG_D(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" Created new UE context uid %u\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->local_uid); + return ue_context_p; + } else { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + return NULL; + } + + return(ue_context_p); +} diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index d703c4c34c..73bd93e737 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -73,10 +73,34 @@ rrc_gNB_get_ue_context( rnti_t rntiP ); +void rrc_gNB_free_mem_UE_context( + const protocol_ctxt_t *const ctxt_pP, + struct rrc_gNB_ue_context_s *const ue_context_pP +); + void rrc_gNB_remove_ue_context( const protocol_ctxt_t* const ctxt_pP, gNB_RRC_INST* rrc_instance_pP, struct rrc_gNB_ue_context_s* ue_context_pP ); +struct rrc_gNB_ue_context_s * +rrc_gNB_ue_context_random_exist( + gNB_RRC_INST *rrc_instance_pP, + const uint64_t ue_identityP +); + +struct rrc_gNB_ue_context_s * +rrc_gNB_ue_context_5g_s_tmsi_exist( + gNB_RRC_INST *rrc_instance_pP, + const uint64_t s_TMSI +); + +struct rrc_gNB_ue_context_s * +rrc_gNB_get_next_free_ue_context( + const protocol_ctxt_t *const ctxt_pP, + gNB_RRC_INST *rrc_instance_pP, + const uint64_t ue_identityP +); + #endif diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c index cacff5cf5c..c4cd41c5b4 100644 --- a/openair2/RRC/NR/rrc_gNB_internode.c +++ b/openair2/RRC/NR/rrc_gNB_internode.c @@ -37,6 +37,7 @@ #include "NR_UE-CapabilityRAT-ContainerList.h" #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" +#include "executables/softmodem-common.h" int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m) { if (CG_ConfigInfo->criticalExtensions.present == NR_CG_ConfigInfo__criticalExtensions_PR_c1) { @@ -46,10 +47,10 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2 if (cg_ConfigInfo->ue_CapabilityInfo) { // Decode UE-CapabilityRAT-ContainerList - LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList=NULL; - UE_CapabilityRAT_ContainerList = calloc(1,sizeof(LTE_UE_CapabilityRAT_ContainerList_t)); + NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList=NULL; + UE_CapabilityRAT_ContainerList = calloc(1,sizeof(NR_UE_CapabilityRAT_ContainerList_t)); asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_LTE_UE_CapabilityRAT_ContainerList, + &asn_DEF_NR_UE_CapabilityRAT_ContainerList, (void **)&UE_CapabilityRAT_ContainerList, cg_ConfigInfo->ue_CapabilityInfo->buf, cg_ConfigInfo->ue_CapabilityInfo->size, 0, 0); @@ -95,33 +96,48 @@ int generate_CG_Config(gNB_RRC_INST *rrc, (const char *)buffer, (enc_rval.encoded+7)>>3); total_size = (enc_rval.encoded+7)>>3; - LOG_I(RRC,"Dumping NR_RRCReconfiguration message (%jd bytes)\n",(enc_rval.encoded+7)>>3); - for (int i=0; i<(enc_rval.encoded+7)>>3; i++) { - printf("%02x",((uint8_t *)buffer)[i]); + FILE *fd; // file to be generated for nr-ue + if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa == 1) { + // This is for phytest only, emulate first X2 message if uecap.raw file is present + LOG_I(RRC,"Dumping NR_RRCReconfiguration message (%jd bytes)\n",(enc_rval.encoded+7)>>3); + for (int i=0; i<(enc_rval.encoded+7)>>3; i++) { + printf("%02x",((uint8_t *)buffer)[i]); + } + printf("\n"); + fd = fopen("reconfig.raw","w"); + if (fd != NULL) { + fwrite((void *)buffer,1,(size_t)((enc_rval.encoded+7)>>3),fd); + fclose(fd); + } } - - printf("\n"); - FILE *fd = fopen("reconfig.raw","w"); - fwrite((void *)buffer,1,(size_t)((enc_rval.encoded+7)>>3),fd); - fclose(fd); + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig, NULL, (void *)rbconfig, buffer, 1024); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", - enc_rval.failed_type->name, enc_rval.encoded); + enc_rval.failed_type->name, enc_rval.encoded); cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config = calloc(1,sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(cg_Config->criticalExtensions.choice.c1->choice.cg_Config->scg_RB_Config, - (const char *)buffer, - (enc_rval.encoded+7)>>3); - LOG_I(RRC,"Dumping scg_RB_Config message (%jd bytes)\n",(enc_rval.encoded+7)>>3); + (const char *)buffer, + (enc_rval.encoded+7)>>3); - for (int i=0; i<(enc_rval.encoded+7)>>3; i++) { - printf("%02x",((uint8_t *)buffer)[i]); + + + if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra > 0 || get_softmodem_params()->sa == 1) { + + LOG_I(RRC,"Dumping scg_RB_Config message (%jd bytes)\n",(enc_rval.encoded+7)>>3); + for (int i=0; i<(enc_rval.encoded+7)>>3; i++) { + printf("%02x",((uint8_t *)buffer)[i]); + } + + printf("\n"); + fd = fopen("rbconfig.raw","w"); + if (fd != NULL) { + fwrite((void *)buffer,1,(size_t)((enc_rval.encoded+7)>>3),fd); + fclose(fd); + } } - - printf("\n"); - fd = fopen("rbconfig.raw","w"); - fwrite((void *)buffer,1,(size_t)((enc_rval.encoded+7)>>3),fd); - fclose(fd); + total_size = total_size + ((enc_rval.encoded+7)>>3); return(total_size); } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 7b7647a746..a390d05a08 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -62,7 +62,7 @@ extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * con const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) { +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m, NR_CG_ConfigInfo_IEs_t *cg_config_info) { struct rrc_gNB_ue_context_s *ue_context_p = NULL; OCTET_STRING_t *ueCapabilityRAT_Container_nr=NULL; @@ -74,8 +74,8 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_Container AssertFatal((list_size=UE_CapabilityRAT_ContainerList->list.count) >= 2, "UE_CapabilityRAT_ContainerList->list.size %d < 2\n",UE_CapabilityRAT_ContainerList->list.count); for (int i=0; ilist.array[i]->rat_Type == LTE_RAT_Type_nr) ueCapabilityRAT_Container_nr = &UE_CapabilityRAT_ContainerList->list.array[i]->ueCapabilityRAT_Container; - else if (UE_CapabilityRAT_ContainerList->list.array[i]->rat_Type == LTE_RAT_Type_eutra_nr) ueCapabilityRAT_Container_MRDC = &UE_CapabilityRAT_ContainerList->list.array[i]->ueCapabilityRAT_Container; + if (UE_CapabilityRAT_ContainerList->list.array[i]->rat_Type == NR_RAT_Type_nr) ueCapabilityRAT_Container_nr = &UE_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container; + else if (UE_CapabilityRAT_ContainerList->list.array[i]->rat_Type == NR_RAT_Type_eutra_nr) ueCapabilityRAT_Container_MRDC = &UE_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container; } // decode and store capabilities @@ -148,10 +148,10 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ // generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331) rrc_gNB_carrier_data_t *carrier=&rrc->carrier; MessageDef *msg; - msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; - protocol_ctxt_t ctxt; + protocol_ctxt_t ctxt={0}; // NR RRCReconfiguration AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n"); ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t)); @@ -162,7 +162,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t)); ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies; carrier->initial_csi_index[rrc->Nb_ue] = 0; - if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1){ + if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){ ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); fill_default_rbconfig(ue_context_p->ue_context.rb_config); } @@ -183,7 +183,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ if (m->nb_e_rabs_tobeadded>0) { for (int i=0; inb_e_rabs_tobeadded; i++) { - // Add the new E-RABs at the corresponding rrc ue context of the gNB + // Add the new E-RABs at the corresponding rrc ue context of the gNB ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id; ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid; memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t)); @@ -243,12 +243,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ } } else LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n"); - } - if (m != NULL) { X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id; X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; - //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size // Send to X2 entity to transport to MeNB asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, @@ -258,6 +255,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ 1024); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3; itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding + } else if (get_softmodem_params()->do_ra) { + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id); } rrc->Nb_ue++; @@ -272,6 +271,15 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_id_rnti, ue_context_p->ue_context.secondaryCellGroup); + if(m == NULL){ + LOG_W(RRC, "Calling RRC PDCP/RLC ASN1 request functions for protocol context %p with module_id %d, rnti %x, frame %d, subframe %d eNB_index %d \n", &ctxt, + ctxt.module_id, + ctxt.rnti, + ctxt.frame, + ctxt.subframe, + ctxt.eNB_index); + } + nr_rrc_pdcp_config_asn1_req( &ctxt, (NR_SRB_ToAddModList_t *) NULL, @@ -292,6 +300,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ (LTE_PMCH_InfoList_r9_t *) NULL, ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + LOG_D(RRC, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %x\n", __FUNCTION__, __LINE__, ctxt.rnti); + } void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { @@ -316,7 +326,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { mac_remove_nr_ue(rrc->module_id, rnti); /* delete gtp tunnel */ - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = rnti; GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 1; diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index c84872ec45..719b73261a 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -43,10 +43,104 @@ #include "common/utils/nr/nr_common.h" #include "SIMULATION/TOOLS/sim.h" #include "executables/softmodem-common.h" +#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #define false 0 #define true 1 +void fill_default_initialDownlinkBWP(NR_BWP_Downlink_t *bwp, NR_ServingCellConfigCommon_t *servingcellconfigcommon) { + + bwp->bwp_Id = 0; + + bwp->bwp_Common=calloc(1,sizeof(*bwp->bwp_Common)); + memcpy((void*)&bwp->bwp_Common, + &servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP, + sizeof(bwp->bwp_Common)); + + bwp->bwp_Dedicated=calloc(1,sizeof(*bwp->bwp_Dedicated)); + bwp->bwp_Dedicated->pdsch_Config = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config)); + bwp->bwp_Dedicated->pdsch_Config->present = NR_SetupRelease_PDSCH_Config_PR_setup; + bwp->bwp_Dedicated->pdsch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0; +} + +void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellConfigCommon_t *servingcellconfigcommon) { + + coreset0->controlResourceSetId = 0; + + // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B, + if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6); + coreset0->frequencyDomainResources.buf[0] = 0xff; + coreset0->frequencyDomainResources.buf[1] = 0; + coreset0->frequencyDomainResources.buf[2] = 0; + coreset0->frequencyDomainResources.buf[3] = 0; + coreset0->frequencyDomainResources.buf[4] = 0; + coreset0->frequencyDomainResources.buf[5] = 0; + coreset0->frequencyDomainResources.size = 6; + coreset0->frequencyDomainResources.bits_unused = 3; + coreset0->duration = 1; + coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved; + coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved)); + coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6; + coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2; + coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = servingcellconfigcommon->physCellId; + coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; + + if(coreset0->tci_StatesPDCCH_ToAddList == NULL) coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList)); + + NR_TCI_StateId_t *tci[8]; + for (int i=0;i<8;i++) { + tci[i]=calloc(1,sizeof(*tci[i])); + *tci[i] = i; + ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]); + } + coreset0->tci_StatesPDCCH_ToReleaseList = NULL; + coreset0->tci_PresentInDCI = NULL; + coreset0->pdcch_DMRS_ScramblingID = NULL; + +} + +void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) { + + if(ss0->controlResourceSetId == NULL) ss0->controlResourceSetId=calloc(1,sizeof(*ss0->controlResourceSetId)); + if(ss0->monitoringSymbolsWithinSlot == NULL) ss0->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss0->monitoringSymbolsWithinSlot)); + if(ss0->monitoringSymbolsWithinSlot->buf == NULL) ss0->monitoringSymbolsWithinSlot->buf = calloc(1,2); + if(ss0->nrofCandidates == NULL) ss0->nrofCandidates = calloc(1,sizeof(*ss0->nrofCandidates)); + if(ss0->searchSpaceType == NULL) ss0->searchSpaceType = calloc(1,sizeof(*ss0->searchSpaceType)); + if(ss0->searchSpaceType->choice.common == NULL) ss0->searchSpaceType->choice.common=calloc(1,sizeof(*ss0->searchSpaceType->choice.common)); + if(ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL) ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); + + ss0->searchSpaceId = 0; + *ss0->controlResourceSetId = 0; + ss0->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss0->monitoringSlotPeriodicityAndOffset)); + ss0->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; + ss0->duration=NULL; + + // should be '1100 0000 0000 00'B (LSB first!), first two symols in slot, adjust if needed + ss0->monitoringSymbolsWithinSlot->buf[1] = 0; + ss0->monitoringSymbolsWithinSlot->buf[0] = (1<<7); + ss0->monitoringSymbolsWithinSlot->size = 2; + ss0->monitoringSymbolsWithinSlot->bits_unused = 2; + + // FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1 + ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; + ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; + ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; + ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; + + ss0->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; +} void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CellGroupConfig_t *secondaryCellGroup, @@ -57,66 +151,33 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n"); AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n"); - if(servingcellconfigcommon->ssb_PositionsInBurst->present !=2) - AssertFatal(1==0,"Currenrly implemented only for medium size SSB bitmap\n"); - uint8_t bitmap = servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]; + uint64_t bitmap=0; + switch (servingcellconfigcommon->ssb_PositionsInBurst->present) { + case 1 : + bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.shortBitmap.buf[0])<<56; + break; + case 2 : + bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0])<<56; + break; + case 3 : + for (int i=0; i<8; i++) { + bitmap |= (((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.longBitmap.buf[i])<<((7-i)*8)); + } + break; + default: + AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", servingcellconfigcommon->ssb_PositionsInBurst->present); + } memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t)); secondaryCellGroup->cellGroupId = scg_id; NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); - RLC_BearerConfig->logicalChannelIdentity = 4; - RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); - RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; - RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1; - RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC)); - *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true; - RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); + nr_rlc_bearer_init(RLC_BearerConfig); + if (get_softmodem_params()->do_ra) + nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional); + else + nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am); + nr_rlc_bearer_init_ul_spec(RLC_BearerConfig->mac_LogicalChannelConfig); -#if 0 - - // RLC UM Bi-directional Bearer configuration - RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional; - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional)); - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; - - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; - -#else - - // RLC AM Bearer configuration - RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; - RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am)); - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500; - RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); - *RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15; - -#endif - - RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters)); - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedServingCells = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup)); - *RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false; - RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL; secondaryCellGroup->rlc_BearerToAddModList = calloc(1,sizeof(*secondaryCellGroup->rlc_BearerToAddModList)); ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig); secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig)); @@ -179,10 +240,41 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb; secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb)); secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0; - struct NR_CFRA_SSB_Resource *ssbElem = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); - ssbElem->ssb = 0; - ssbElem->ra_PreambleIndex= 63; - ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem); + struct NR_CFRA_SSB_Resource *ssbElem[8]; + ssbElem[0] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[0]->ssb = 0; + ssbElem[0]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[0]); +#if 0 + ssbElem[1] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[1]->ssb = 1; + ssbElem[1]->ra_PreambleIndex = 62; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[1]); + ssbElem[2] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[2]->ssb = 2; + ssbElem[2]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[2]); + ssbElem[3] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[3]->ssb = 3; + ssbElem[3]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[3]); + ssbElem[4] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[4]->ssb = 4; + ssbElem[4]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[4]); + ssbElem[5] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[5]->ssb = 5; + ssbElem[5]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[5]); + ssbElem[6] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[6]->ssb = 6; + ssbElem[6]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[6]); + ssbElem[7] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem[7]->ssb = 7; + ssbElem[7]->ra_PreambleIndex = 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[7]); +#endif secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup; @@ -191,7 +283,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n310 = NR_RLF_TimersAndConstants__n310_n10; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->n311 = NR_RLF_TimersAndConstants__n311_n1; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1 = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1)); - secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311_v1530 = NR_RLF_TimersAndConstants__ext1__t311_v1530_ms30000; + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup->ext1->t311 = NR_RLF_TimersAndConstants__ext1__t311_ms30000; secondaryCellGroup->spCellConfig->rlmInSyncOutOfSyncThreshold = NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->tdd_UL_DL_ConfigurationDedicated = NULL; @@ -220,9 +312,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList)); int n_ssb = 0; - NR_TCI_State_t *tcic[8]; - for (int i=0;i<8;i++) { - if ((bitmap>>(7-i))&0x01){ + NR_TCI_State_t *tcic[64]; + for (int i=0;i<64;i++) { + if ((bitmap>>(63-i))&0x01){ tcic[i]=calloc(1,sizeof(*tcic[i])); tcic[i]->tci_StateId=n_ssb; tcic[i]->qcl_Type1.cell=NULL; @@ -331,7 +423,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1; - secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table=NULL; + if (!get_softmodem_params()->use_256qam_table) { + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table=NULL; + } else { + secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table)); + *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256; + } secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI)); *secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1; secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; @@ -381,12 +478,21 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet)); + int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset)); coreset->controlResourceSetId=1; - // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B, + // frequency domain resources depends on BWP size + // options are 24, 48 or 96 coreset->frequencyDomainResources.buf = calloc(1,6); - coreset->frequencyDomainResources.buf[0] = 0xff; - coreset->frequencyDomainResources.buf[1] = 0xff; + if (curr_bwp < 48) + coreset->frequencyDomainResources.buf[0] = 0xf0; + else + coreset->frequencyDomainResources.buf[0] = 0xff; + if (curr_bwp < 96) + coreset->frequencyDomainResources.buf[1] = 0; + else + coreset->frequencyDomainResources.buf[1] = 0xff; coreset->frequencyDomainResources.buf[2] = 0; coreset->frequencyDomainResources.buf[3] = 0; coreset->frequencyDomainResources.buf[4] = 0; @@ -398,9 +504,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList)); - NR_TCI_StateId_t *tci[8]; - for (int i=0;i<8;i++) { - if ((bitmap>>(7-i))&0x01){ + NR_TCI_StateId_t *tci[64]; + for (int i=0;i<64;i++) { + if ((bitmap>>(63-i))&0x01){ tci[i]=calloc(1,sizeof(*tci[i])); *tci[i] = i; ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); @@ -444,7 +550,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss); - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=NULL; + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1)); + *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=0; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->pagingSearchSpace=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)); @@ -500,7 +607,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ss2->nrofCandidates=calloc(1,sizeof(*ss2->nrofCandidates)); ss2->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; ss2->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4; + if (curr_bwp < 48) + ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; + else if (curr_bwp < 96) + ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2; + else + ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4; ss2->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; ss2->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; ss2->searchSpaceType=calloc(1,sizeof(*ss2->searchSpaceType)); @@ -622,9 +734,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco n_ssb = 0; - NR_TCI_State_t *tcid[8]; - for (int i=0;i<8;i++) { - if ((bitmap>>(7-i))&0x01){ + NR_TCI_State_t *tcid[64]; + for (int i=0;i<64;i++) { + if ((bitmap>>(63-i))&0x01){ tcid[i]=calloc(1,sizeof(*tcid[i])); tcid[i]->tci_StateId=n_ssb; tcid[i]->qcl_Type1.cell=NULL; @@ -649,7 +761,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL; + if (!get_softmodem_params()->use_256qam_table) { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL; + } else { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table)); + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256; + } bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1; bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; @@ -675,7 +792,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL; + if (!get_softmodem_params()->use_256qam_table) { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL; + } else { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table)); + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256; + } bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI)); *bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1; bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; @@ -766,8 +888,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pusch_Config->pusch_AggregationFactor=NULL; pusch_Config->mcs_Table=NULL; pusch_Config->mcs_TableTransformPrecoder=NULL; - pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder)); - *pusch_Config->transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; + pusch_Config->transformPrecoder= NULL; + /* if msg3_transformprecoding is set in conf file - pusch config should not disable it */ + if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) { + pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder)); + *pusch_Config->transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled; + } pusch_Config->codebookSubset=calloc(1,sizeof(*pusch_Config->codebookSubset)); *pusch_Config->codebookSubset = NR_PUSCH_Config__codebookSubset_nonCoherent; pusch_Config->maxRank=calloc(1,sizeof(*pusch_Config->maxRank)); @@ -776,6 +902,39 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco pusch_Config->uci_OnPUSCH=NULL; pusch_Config->tp_pi2BPSK=NULL; + /*------------------------------TRANSFORM PRECODING- -----------------------------------------------------------------------*/ + + uint8_t transform_precoding = NR_PUSCH_Config__transformPrecoder_disabled; + + // TBD: configure this from .conf file, Dedicated params cannot yet be configured in .conf file. + // Enable this to test transform precoding enabled from dedicated config. + /*if (pusch_Config->transformPrecoder == NULL) + pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder)); + + *pusch_Config->transformPrecoder = NR_PUSCH_Config__transformPrecoder_enabled; */ + // END ------- + + if (pusch_Config->transformPrecoder == NULL) { + if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder != NULL) + transform_precoding = NR_PUSCH_Config__transformPrecoder_enabled; + } + else + transform_precoding = *pusch_Config->transformPrecoder; + + + if (transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled ) { + /* Enable DMRS uplink config for transform precoding enabled */ + NR_DMRS_UplinkConfig->transformPrecodingEnabled = calloc(1,sizeof(*NR_DMRS_UplinkConfig->transformPrecodingEnabled)); + NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity = NULL; + NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceGroupHopping = NULL; + NR_DMRS_UplinkConfig->transformPrecodingEnabled->sequenceHopping = NULL; + NR_DMRS_UplinkConfig->transformPrecodingEnabled->ext1 = NULL; + + LOG_I(RRC,"TRANSFORM PRECODING ENABLED......\n"); + + } + /*----------------------------------------------------------------------------------------------------------------------------*/ + initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); initialUplinkBWP->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; NR_SRS_Config_t *srs_Config = calloc(1,sizeof(*srs_Config)); @@ -863,7 +1022,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); *pucchresset0id1=2; ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id1); - pucchresset0->maxPayloadMinus1=NULL; + pucchresset0->maxPayloadSize=NULL; ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); @@ -874,7 +1033,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); *pucchresset1id1=4; ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id1); - pucchresset1->maxPayloadMinus1=NULL; + pucchresset1->maxPayloadSize=NULL; ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); @@ -884,7 +1043,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3)); pucchres0->pucch_ResourceId=1; - pucchres0->startingPRB=48; + pucchres0->startingPRB=8; pucchres0->intraSlotFrequencyHopping=NULL; pucchres0->secondHopPRB=NULL; pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -895,7 +1054,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); pucchres1->pucch_ResourceId=2; - pucchres1->startingPRB=48; + pucchres1->startingPRB=8; pucchres1->intraSlotFrequencyHopping=NULL; pucchres1->secondHopPRB=NULL; pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0; @@ -906,23 +1065,23 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres1); pucchres2->pucch_ResourceId=3; - pucchres2->startingPRB=40; + pucchres2->startingPRB=0; pucchres2->intraSlotFrequencyHopping=NULL; pucchres2->secondHopPRB=NULL; pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=4; + pucchres2->format.choice.format2->nrofPRBs=8; pucchres2->format.choice.format2->nrofSymbols=1; pucchres2->format.choice.format2->startingSymbolIndex=13; ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); pucchres3->pucch_ResourceId=4; - pucchres3->startingPRB=40; + pucchres3->startingPRB=0; pucchres3->intraSlotFrequencyHopping=NULL; pucchres3->secondHopPRB=NULL; pucchres3->format.present= NR_PUCCH_Resource__format_PR_format2; pucchres3->format.choice.format2=calloc(1,sizeof(*pucchres3->format.choice.format2)); - pucchres3->format.choice.format2->nrofPRBs=4; + pucchres3->format.choice.format2->nrofPRBs=8; pucchres3->format.choice.format2->nrofSymbols=1; pucchres3->format.choice.format2->startingSymbolIndex=12; ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres3); @@ -1018,7 +1177,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup = pdsch_servingcellconfig; pdsch_servingcellconfig->codeBlockGroupTransmission = NULL; pdsch_servingcellconfig->xOverhead = NULL; - pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NULL; + pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = calloc(1, sizeof(*pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH)); + *pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = NR_PDSCH_ServingCellConfig__nrofHARQ_ProcessesForPDSCH_n16; pdsch_servingcellconfig->pucch_Cell= NULL; pdsch_servingcellconfig->ext1=calloc(1,sizeof(*pdsch_servingcellconfig->ext1)); pdsch_servingcellconfig->ext1->maxMIMO_Layers = calloc(1,sizeof(*pdsch_servingcellconfig->ext1->maxMIMO_Layers)); @@ -1086,45 +1246,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco /*NR_CSI_SSB_ResourceSet_t *ssbresset0 = calloc(1,sizeof(*ssbresset0)); ssbresset0->csi_SSB_ResourceSetId=0; - if ((bitmap>>7)&0x01){ - NR_SSB_Index_t *ssbresset00=calloc(1,sizeof(*ssbresset00)); - *ssbresset00=0; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset00); - } - if ((bitmap>>6)&0x01) { - NR_SSB_Index_t *ssbresset01=calloc(1,sizeof(*ssbresset01)); - *ssbresset01=1; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset01); - } - if ((bitmap>>5)&0x01) { - NR_SSB_Index_t *ssbresset02=calloc(1,sizeof(*ssbresset02)); - *ssbresset02=2; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset02); - } - if ((bitmap>>4)&0x01) { - NR_SSB_Index_t *ssbresset03=calloc(1,sizeof(*ssbresset03)); - *ssbresset03=3; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset03); - } - if ((bitmap>>3)&0x01) { - NR_SSB_Index_t *ssbresset04=calloc(1,sizeof(*ssbresset04)); - *ssbresset04=4; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset04); - } - if ((bitmap>>2)&0x01) { - NR_SSB_Index_t *ssbresset05=calloc(1,sizeof(*ssbresset05)); - *ssbresset05=5; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset05); - } - if ((bitmap>>1)&0x01) { - NR_SSB_Index_t *ssbresset06=calloc(1,sizeof(*ssbresset06)); - *ssbresset06=6; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset06); - } - if ((bitmap)&0x01) { - NR_SSB_Index_t *ssbresset07=calloc(1,sizeof(*ssbresset07)); - *ssbresset07=7; - ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset07); + + NR_SSB_Index_t *ssbresset[64]; + for (int i=0;i<64;i++) { + if ((bitmap>>(63-i))&0x01){ + ssbresset[i]=calloc(1,sizeof(*ssbresset[i])); + *ssbresset[i] = i; + ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset[i]); + } } ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);*/ @@ -1293,5 +1422,37 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); } +/* Function to set or overwrite PTRS DL RRC parameters */ +void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset) +{ + int i=0; + /* check for memory allocation */ + if(bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS == NULL) { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->present = NR_SetupRelease_PTRS_DownlinkConfig_PR_setup; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup= calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio = calloc(1,sizeof(long)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset = calloc(1,sizeof(long)); + /* Fill the given values */ + for(i = 0; i < 2; i++) { + ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list,&ptrsNrb[i]); + } + for(i = 0; i < 3; i++) { + ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list,&ptrsMcs[i]); + } + }// if memory exist then over write the old values + else { + for(i = 0; i < 2; i++) { + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->frequencyDensity->list.array[i] = ptrsNrb[i]; + } + for(i = 0; i < 3; i++) { + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->timeDensity->list.array[i] = ptrsMcs[i]; + } + } + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->epre_Ratio = *epre_Ratio; + *bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS->choice.setup->resourceElementOffset = *reOffset; +} #endif diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 08976522b0..5ad6746696 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -46,16 +46,17 @@ nr_mac_rrc_data_ind_ue( const sdu_size_t pdu_len){ switch(channel){ - case NR_BCCH_BCH: - AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message( module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); - break; - default: - break; + case NR_BCCH_BCH: + AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); + break; + case NR_BCCH_DL_SCH: + AssertFatal( nr_rrc_ue_decode_NR_SIB1_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-DLSCH error!\n"); + break; + default: + break; } - return(0); - } int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, @@ -67,4 +68,43 @@ int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, // todo return 0; -} \ No newline at end of file +} + +uint8_t +rrc_data_req_ue( + const protocol_ctxt_t *const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t *const buffer_pP, + const pdcp_transmission_mode_t modeP +) +{ + MessageDef *message_p; + // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). + uint8_t *message_buffer; + message_buffer = itti_malloc ( + ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, + ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, + sdu_sizeP); + memcpy (message_buffer, buffer_pP, sdu_sizeP); + message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, 0, RRC_DCCH_DATA_REQ); + RRC_DCCH_DATA_REQ (message_p).frame = ctxt_pP->frame; + RRC_DCCH_DATA_REQ (message_p).enb_flag = ctxt_pP->enb_flag; + RRC_DCCH_DATA_REQ (message_p).rb_id = rb_idP; + RRC_DCCH_DATA_REQ (message_p).muip = muiP; + RRC_DCCH_DATA_REQ (message_p).confirmp = confirmP; + RRC_DCCH_DATA_REQ (message_p).sdu_size = sdu_sizeP; + RRC_DCCH_DATA_REQ (message_p).sdu_p = message_buffer; + RRC_DCCH_DATA_REQ (message_p).mode = modeP; + RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id; + RRC_DCCH_DATA_REQ (message_p).rnti = ctxt_pP->rnti; + RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index; + itti_send_msg_to_task ( + TASK_PDCP_UE, + ctxt_pP->instance, + message_p); + return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + +} diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c old mode 100755 new mode 100644 index 1e182eff8b..b6c0ae4b45 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -33,10 +33,17 @@ #define RRC_UE #define RRC_UE_C -#include "NR_DL-DCCH-Message.h" //asn_DEF_NR_DL_DCCH_Message -#include "NR_BCCH-BCH-Message.h" //asn_DEF_NR_BCCH_BCH_Message -#include "NR_CellGroupConfig.h" //asn_DEF_NR_CellGroupConfig -#include "NR_BWP-Downlink.h" //asn_DEF_NR_BWP_Downlink +#include "asn1_conversions.h" + +#include "NR_DL-DCCH-Message.h" //asn_DEF_NR_DL_DCCH_Message +#include "NR_DL-CCCH-Message.h" //asn_DEF_NR_DL_CCCH_Message +#include "NR_BCCH-BCH-Message.h" //asn_DEF_NR_BCCH_BCH_Message +#include "NR_BCCH-DL-SCH-Message.h" //asn_DEF_NR_BCCH_DL_SCH_Message +#include "NR_CellGroupConfig.h" //asn_DEF_NR_CellGroupConfig +#include "NR_BWP-Downlink.h" //asn_DEF_NR_BWP_Downlink +#include "NR_RRCReconfiguration.h" +#include "NR_MeasConfig.h" +#include "NR_UL-DCCH-Message.h" #include "rrc_list.h" #include "rrc_defs.h" @@ -44,11 +51,158 @@ #include "rrc_vars.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" -#include "executables/softmodem-common.h" +#include "intertask_interface.h" +#include "executables/softmodem-common.h" +#include "plmn_data.h" +#include "pdcp.h" +#include "UTIL/OSA/osa_defs.h" +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +#ifndef CELLULAR + #include "RRC/NR/MESSAGES/asn1_msg.h" +#endif + +#include "RRC/NAS/nas_config.h" +#include "RRC/NAS/rb_config.h" +#include "SIMULATION/TOOLS/sim.h" // for taus + +#if ITTI_SIM +#include "nr_nas_msg_sim.h" +#endif + +/* NAS Attach request with IMSI */ +static const char nr_nas_attach_req_imsi[] = { + 0x07, 0x41, + /* EPS Mobile identity = IMSI */ + 0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87, + 0xF9, + /* End of EPS Mobile Identity */ + 0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03, + 0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00, + 0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2, + 0x01, 0x27, 0x11, +}; + +extern void pdcp_config_set_security( + const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, + const rb_id_t rb_idP, + const uint16_t lc_idP, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc +); + +void +nr_rrc_ue_process_ueCapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + NR_UECapabilityEnquiry_t *UECapabilityEnquiry, + uint8_t gNB_index +); + +void +nr_sa_rrc_ue_process_radioBearerConfig( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + NR_RadioBearerConfig_t *const radioBearerConfig +); + +uint8_t do_NR_RRCReconfigurationComplete( + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + const uint8_t Transaction_id + ); + +void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ); + +void +nr_rrc_ue_generate_rrcReestablishmentComplete( + const protocol_ctxt_t *const ctxt_pP, + NR_RRCReestablishment_t *rrcReestablishment, + uint8_t gNB_index +); + +mui_t nr_rrc_mui=0; +uint8_t first_rrcreconfigurationcomplete = 0; + +static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) { + return NR_UE_rrc_inst[ue_mod_idP].nrRrcState; +} + + +static Rrc_Sub_State_NR_t nr_rrc_get_sub_state (module_id_t ue_mod_idP) { + return NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState; +} + +static int nr_rrc_set_state (module_id_t ue_mod_idP, Rrc_State_NR_t state) { + AssertFatal ((RRC_STATE_FIRST_NR <= state) && (state <= RRC_STATE_LAST_NR), + "Invalid state %d!\n", state); + + if (NR_UE_rrc_inst[ue_mod_idP].nrRrcState != state) { + NR_UE_rrc_inst[ue_mod_idP].nrRrcState = state; + return (1); + } + + return (0); +} + +static int nr_rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_NR_t subState ) { + if (AMF_MODE_ENABLED) { + switch (NR_UE_rrc_inst[ue_mod_idP].nrRrcState) { + case RRC_STATE_INACTIVE_NR: + AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST_NR), + "Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState); + break; + + case RRC_STATE_IDLE_NR: + AssertFatal ((RRC_SUB_STATE_IDLE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST_NR), + "Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState); + break; + + case RRC_STATE_CONNECTED_NR: + AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST_NR), + "Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState); + break; + } + } + + if (NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState != subState) { + NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState = subState; + return (1); + } + + return (0); +} + +extern boolean_t nr_rrc_pdcp_config_asn1_req( + const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 + #endif + ,rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + +extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const NR_SRB_ToAddModList_t * const srb2add_listP, + const NR_DRB_ToAddModList_t * const drb2add_listP, + const NR_DRB_ToReleaseList_t * const drb2release_listP, + const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded) int8_t nr_rrc_ue_decode_secondary_cellgroup_config( + const module_id_t module_id, const uint8_t *buffer, const uint32_t size ){ @@ -72,11 +226,11 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config( return -1; } - if(NR_UE_rrc_inst->cell_group_config == NULL){ - NR_UE_rrc_inst->cell_group_config = cell_group_config; - nr_rrc_ue_process_scg_config(cell_group_config); + if(NR_UE_rrc_inst[module_id].cell_group_config == NULL){ + NR_UE_rrc_inst[module_id].cell_group_config = cell_group_config; + nr_rrc_ue_process_scg_config(module_id,cell_group_config); }else{ - nr_rrc_ue_process_scg_config(cell_group_config); + nr_rrc_ue_process_scg_config(module_id,cell_group_config); SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0); } @@ -96,67 +250,62 @@ int8_t nr_rrc_ue_process_RadioBearerConfig(NR_RadioBearerConfig_t *RadioBearerCo // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded) // RRCReconfiguration -int8_t nr_rrc_ue_process_rrcReconfiguration(NR_RRCReconfiguration_t *rrcReconfiguration){ +int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration){ - switch(rrcReconfiguration->criticalExtensions.present){ - case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){ - if(NR_UE_rrc_inst->radio_bearer_config == NULL){ - NR_UE_rrc_inst->radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; - }else{ - nr_rrc_ue_process_RadioBearerConfig(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig); - } - } + switch(rrcReconfiguration->criticalExtensions.present){ + case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration: + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){ + if(NR_UE_rrc_inst[module_id].radio_bearer_config == NULL){ + NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; + }else{ + nr_rrc_ue_process_RadioBearerConfig(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig); + } + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ + NR_CellGroupConfig_t *cellGroupConfig = NULL; + uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, //might be added prefix later + (void **)&cellGroupConfig, + (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, + rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0); - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ - NR_CellGroupConfig_t *cellGroupConfig = NULL; - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf, - rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0); + xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig); - xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)cellGroupConfig); + if(NR_UE_rrc_inst[module_id].cell_group_config == NULL){ + // first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time. + NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; + nr_rrc_ue_process_scg_config(module_id,cellGroupConfig); + }else{ + // after first time, update it and free the memory after. + SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst[module_id].cell_group_config, 0); + NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig; + nr_rrc_ue_process_scg_config(module_id,cellGroupConfig); + } + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){ + if(NR_UE_rrc_inst[module_id].meas_config == NULL){ + NR_UE_rrc_inst[module_id].meas_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig; + }else{ + // if some element need to be updated + nr_rrc_ue_process_meas_config(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig); + } + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->lateNonCriticalExtension != NULL){ + // unuse now + } + if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->nonCriticalExtension != NULL){ + // unuse now + } + break; + + case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING: + case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture: + default: + break; + } + //nr_rrc_mac_config_req_ue(); - if(NR_UE_rrc_inst->cell_group_config == NULL){ - // first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time. - NR_UE_rrc_inst->cell_group_config = cellGroupConfig; - nr_rrc_ue_process_scg_config(cellGroupConfig); - }else{ - // after first time, update it and free the memory after. - SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst->cell_group_config, 0); - NR_UE_rrc_inst->cell_group_config = cellGroupConfig; - nr_rrc_ue_process_scg_config(cellGroupConfig); - } - - } - - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){ - if(NR_UE_rrc_inst->meas_config == NULL){ - NR_UE_rrc_inst->meas_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig; - }else{ - // if some element need to be updated - nr_rrc_ue_process_meas_config(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig); - } - - } - - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->lateNonCriticalExtension != NULL){ - // unuse now - } - - if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->nonCriticalExtension != NULL){ - // unuse now - } - break; - case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING: - case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture: - default: - break; - } - //nr_rrc_mac_config_req_ue(); - - return 0; + return 0; } @@ -166,90 +315,89 @@ int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){ return 0; } -int8_t nr_rrc_ue_process_scg_config(NR_CellGroupConfig_t *cell_group_config){ - int i; - if(NR_UE_rrc_inst->cell_group_config==NULL){ - // initial list - if(cell_group_config->spCellConfig != NULL){ - if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ - if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ - for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ - RRC_LIST_MOD_ADD(NR_UE_rrc_inst->BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); - } - } - } - } - }else{ - // maintain list - if(cell_group_config->spCellConfig != NULL){ - if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ - // process element of list to be add by RRC message - if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ - for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ - RRC_LIST_MOD_ADD(NR_UE_rrc_inst->BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); - } - } - - - // process element of list to be release by RRC message - if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList != NULL){ - for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.count; ++i){ - NR_BWP_Downlink_t *freeP = NULL; - RRC_LIST_MOD_REL(NR_UE_rrc_inst->BWP_Downlink_list, bwp_Id, *cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.array[i], freeP); - if(freeP != NULL){ - SEQUENCE_free(&asn_DEF_NR_BWP_Downlink, (void *)freeP, 0); - } - } - } - } +int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config){ + int i; + if(NR_UE_rrc_inst[module_id].cell_group_config==NULL){ + // initial list + if(cell_group_config->spCellConfig != NULL){ + if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ + if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ + for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ + RRC_LIST_MOD_ADD(NR_UE_rrc_inst[module_id].BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); + } + } + } + } + }else{ + // maintain list + if(cell_group_config->spCellConfig != NULL){ + if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ + // process element of list to be add by RRC message + if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ + for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){ + RRC_LIST_MOD_ADD(NR_UE_rrc_inst[module_id].BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id); + } } - } - return 0; + // process element of list to be release by RRC message + if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList != NULL){ + for(i=0; ispCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.count; ++i){ + NR_BWP_Downlink_t *freeP = NULL; + RRC_LIST_MOD_REL(NR_UE_rrc_inst[module_id].BWP_Downlink_list, bwp_Id, *cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.array[i], freeP); + if(freeP != NULL){ + SEQUENCE_free(&asn_DEF_NR_BWP_Downlink, (void *)freeP, 0); + } + } + } + } + } + } + + return 0; } - - void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message,int msg_len) { - + module_id_t module_id=0; // TODO switch (nsa_message_type) { case nr_SecondaryCellGroupConfig_r15: { - NR_RRCReconfiguration_t *RRCReconfiguration=NULL; - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_RRCReconfiguration, - (void **)&RRCReconfiguration, - (uint8_t *)message, - msg_len); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC,"NR_RRCReconfiguration decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); - return; - } - nr_rrc_ue_process_rrcReconfiguration(RRCReconfiguration); - } + NR_RRCReconfiguration_t *RRCReconfiguration=NULL; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_RRCReconfiguration, + (void **)&RRCReconfiguration, + (uint8_t *)message, + msg_len); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC,"NR_RRCReconfiguration decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); + return; + } + nr_rrc_ue_process_rrcReconfiguration(module_id,RRCReconfiguration); + } break; + case nr_RadioBearerConfigX_r15: { - NR_RadioBearerConfig_t *RadioBearerConfig=NULL; - asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_NR_RadioBearerConfig, - (void **)&RadioBearerConfig, - (uint8_t *)message, - msg_len); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC,"NR_RadioBearerConfig decode error\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 ); - return; - } - nr_rrc_ue_process_RadioBearerConfig(RadioBearerConfig); + NR_RadioBearerConfig_t *RadioBearerConfig=NULL; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_RadioBearerConfig, + (void **)&RadioBearerConfig, + (uint8_t *)message, + msg_len); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC,"NR_RadioBearerConfig decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 ); + return; + } + nr_rrc_ue_process_RadioBearerConfig(RadioBearerConfig); } break; + default: AssertFatal(1==0,"Unknown message %d\n",nsa_message_type); break; @@ -258,104 +406,105 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, } NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ - - if(NB_NR_UE_INST > 0){ - NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)malloc(NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); - memset(NR_UE_rrc_inst, 0, NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); - - // fill UE-NR-Capability @ UE-CapabilityRAT-Container here. - - // init RRC lists - RRC_LIST_INIT(NR_UE_rrc_inst->RLC_Bearer_Config_list, NR_maxLC_ID); - RRC_LIST_INIT(NR_UE_rrc_inst->SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->TAG_list, NR_maxNrofTAGs); - RRC_LIST_INIT(NR_UE_rrc_inst->TDD_UL_DL_SlotConfig_list, NR_maxNrofSlots); - RRC_LIST_INIT(NR_UE_rrc_inst->BWP_Downlink_list, NR_maxNrofBWPs); - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[0], 3); // for init-dl-bwp - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[1], 3); // for dl-bwp id=0 - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[2], 3); // for dl-bwp id=1 - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[3], 3); // for dl-bwp id=2 - RRC_LIST_INIT(NR_UE_rrc_inst->ControlResourceSet_list[4], 3); // for dl-bwp id=3 - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[0], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[1], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[2], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[3], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SearchSpace_list[4], 10); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[0], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[1], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[2], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[3], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->SlotFormatCombinationsPerCell_list[4], NR_maxNrofAggregatedCellsPerCellGroup); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[0], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[1], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[2], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[3], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->TCI_State_list[4], NR_maxNrofTCI_States); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[0], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[1], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[2], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[3], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->RateMatchPattern_list[4], NR_maxNrofRateMatchPatterns); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[0], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[1], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[2], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[3], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->ZP_CSI_RS_Resource_list[4], NR_maxNrofZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[0], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[1], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[2], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[3], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->Aperidic_ZP_CSI_RS_ResourceSet_list[4], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[0], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[1], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[2], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[3], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->SP_ZP_CSI_RS_ResourceSet_list[4], NR_maxNrofZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->NZP_CSI_RS_Resource_list, NR_maxNrofNZP_CSI_RS_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->NZP_CSI_RS_ResourceSet_list, NR_maxNrofNZP_CSI_RS_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_IM_Resource_list, NR_maxNrofCSI_IM_Resources); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_IM_ResourceSet_list, NR_maxNrofCSI_IM_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_SSB_ResourceSet_list, NR_maxNrofCSI_SSB_ResourceSets); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations); - RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations); - - if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) { - // read in files for RRCReconfiguration and RBconfig - FILE *fd; - char filename[1024]; - if (rrc_config_path) - sprintf(filename,"%s/reconfig.raw",rrc_config_path); - else - sprintf(filename,"reconfig.raw"); - fd = fopen(filename,"r"); - char buffer[1024]; - AssertFatal(fd, - "cannot read file %s: errno %d, %s\n", - filename, - errno, - strerror(errno)); - int msg_len=fread(buffer,1,1024,fd); - fclose(fd); - process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); - if (rrc_config_path) - sprintf(filename,"%s/rbconfig.raw",rrc_config_path); - else - sprintf(filename,"rbconfig.raw"); - fd = fopen(filename,"r"); - AssertFatal(fd, - "cannot read file %s: errno %d, %s\n", - filename, - errno, - strerror(errno)); - msg_len=fread(buffer,1,1024,fd); - fclose(fd); - process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); - } - }else{ - NR_UE_rrc_inst = NULL; + int nr_ue; + if(NB_NR_UE_INST > 0){ + NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)malloc(NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); + memset(NR_UE_rrc_inst, 0, NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t)); + for(nr_ue=0;nr_uephy_test==1 || get_softmodem_params()->do_ra==1 || get_softmodem_params()->sa == 1) { + // read in files for RRCReconfiguration and RBconfig + FILE *fd; + char filename[1024]; + if (rrc_config_path) + sprintf(filename,"%s/reconfig.raw",rrc_config_path); + else + sprintf(filename,"reconfig.raw"); + fd = fopen(filename,"r"); + char buffer[1024]; + AssertFatal(fd, + "cannot read file %s: errno %d, %s\n", + filename, + errno, + strerror(errno)); + int msg_len=fread(buffer,1,1024,fd); + fclose(fd); + process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len); + if (rrc_config_path) + sprintf(filename,"%s/rbconfig.raw",rrc_config_path); + else + sprintf(filename,"rbconfig.raw"); + fd = fopen(filename,"r"); + AssertFatal(fd, + "cannot read file %s: errno %d, %s\n", + filename, + errno, + strerror(errno)); + msg_len=fread(buffer,1,1024,fd); + fclose(fd); + process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); + } + }else{ + NR_UE_rrc_inst = NULL; + } + + return NR_UE_rrc_inst; } @@ -392,7 +541,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( const uint8_t buffer_len ){ int i; NR_BCCH_BCH_Message_t *bcch_message = NULL; - NR_MIB_t *mib = NR_UE_rrc_inst->mib; + NR_MIB_t *mib = NR_UE_rrc_inst[module_id].mib; if(mib != NULL){ SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)mib, 1 ); @@ -412,7 +561,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { printf("NR_BCCH_BCH decode error\n"); for (i=0; i 1) + return "ERR"; + + if (value) + return "notReserved"; + + return "reserved"; +} + +void nr_dump_sib2( NR_SIB2_t *sib2 ){ +//cellReselectionInfoCommon + //nrofSS_BlocksToAverage + if( sib2->cellReselectionInfoCommon.nrofSS_BlocksToAverage) + LOG_I( RRC, "cellReselectionInfoCommon.nrofSS_BlocksToAverage : %ld\n", + *sib2->cellReselectionInfoCommon.nrofSS_BlocksToAverage ); + else + LOG_I( RRC, "cellReselectionInfoCommon->nrofSS_BlocksToAverage : not defined\n" ); + + //absThreshSS_BlocksConsolidation + if( sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation){ + LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdRSRP : %ld\n", + *sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdRSRP ); + LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdRSRQ : %ld\n", + *sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdRSRQ ); + LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdSINR : %ld\n", + *sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdSINR ); + } else + LOG_I( RRC, "cellReselectionInfoCommon->absThreshSS_BlocksConsolidation : not defined\n" ); + + //q_Hyst + LOG_I( RRC, "cellReselectionInfoCommon.q_Hyst : %ld\n", + sib2->cellReselectionInfoCommon.q_Hyst ); + + //speedStateReselectionPars + if( sib2->cellReselectionInfoCommon.speedStateReselectionPars){ + LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.t_Evaluation : %ld\n", + sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_Evaluation); + LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.t_HystNormal : %ld\n", + sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_HystNormal); + LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium : %ld\n", + sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium); + LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh : %ld\n", + sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh); + LOG_I( RRC, "speedStateReselectionPars->q_HystSF.sf_Medium : %ld\n", + sib2->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_Medium); + LOG_I( RRC, "speedStateReselectionPars->q_HystSF.sf_High : %ld\n", + sib2->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_High); + } else + LOG_I( RRC, "cellReselectionInfoCommon->speedStateReselectionPars : not defined\n" ); + +//cellReselectionServingFreqInfo + if( sib2->cellReselectionServingFreqInfo.s_NonIntraSearchP) + LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearchP : %ld\n", + *sib2->cellReselectionServingFreqInfo.s_NonIntraSearchP ); + else + LOG_I( RRC, "cellReselectionServingFreqInfo->s_NonIntraSearchP : not defined\n" ); + + if( sib2->cellReselectionServingFreqInfo.s_NonIntraSearchQ) + LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearchQ : %ld\n", + *sib2->cellReselectionServingFreqInfo.s_NonIntraSearchQ ); + else + LOG_I( RRC, "cellReselectionServingFreqInfo->s_NonIntraSearchQ : not defined\n" ); + + LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLowP : %ld\n", + sib2->cellReselectionServingFreqInfo.threshServingLowP ); + + if( sib2->cellReselectionServingFreqInfo.threshServingLowQ) + LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLowQ : %ld\n", + *sib2->cellReselectionServingFreqInfo.threshServingLowQ ); + else + LOG_I( RRC, "cellReselectionServingFreqInfo->threshServingLowQ : not defined\n" ); + + LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionPriority : %ld\n", + sib2->cellReselectionServingFreqInfo.cellReselectionPriority ); + if( sib2->cellReselectionServingFreqInfo.cellReselectionSubPriority) + LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionSubPriority : %ld\n", + *sib2->cellReselectionServingFreqInfo.cellReselectionSubPriority ); + else + LOG_I( RRC, "cellReselectionServingFreqInfo->cellReselectionSubPriority : not defined\n" ); + +//intraFreqCellReselectionInfo + LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMin : %ld\n", + sib2->intraFreqCellReselectionInfo.q_RxLevMin ); + + if( sib2->intraFreqCellReselectionInfo.q_RxLevMinSUL) + LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMinSUL : %ld\n", + *sib2->intraFreqCellReselectionInfo.q_RxLevMinSUL ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->q_RxLevMinSUL : not defined\n" ); + + if( sib2->intraFreqCellReselectionInfo.q_QualMin) + LOG_I( RRC, "intraFreqCellReselectionInfo.q_QualMin : %ld\n", + *sib2->intraFreqCellReselectionInfo.q_QualMin ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->q_QualMin : not defined\n" ); + + LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearchP : %ld\n", + sib2->intraFreqCellReselectionInfo.s_IntraSearchP ); + + if( sib2->intraFreqCellReselectionInfo.s_IntraSearchQ) + LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearchQ : %ld\n", + *sib2->intraFreqCellReselectionInfo.s_IntraSearchQ ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->s_IntraSearchQ : not defined\n" ); + + LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionNR : %ld\n", + sib2->intraFreqCellReselectionInfo.t_ReselectionNR ); + + if( sib2->intraFreqCellReselectionInfo.frequencyBandList) + LOG_I( RRC, "intraFreqCellReselectionInfo.frequencyBandList : %p\n", + sib2->intraFreqCellReselectionInfo.frequencyBandList ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->frequencyBandList : not defined\n" ); + + if( sib2->intraFreqCellReselectionInfo.frequencyBandListSUL) + LOG_I( RRC, "intraFreqCellReselectionInfo.frequencyBandListSUL : %p\n", + sib2->intraFreqCellReselectionInfo.frequencyBandListSUL ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->frequencyBandListSUL : not defined\n" ); + + if( sib2->intraFreqCellReselectionInfo.p_Max) + LOG_I( RRC, "intraFreqCellReselectionInfo.p_Max : %ld\n", + *sib2->intraFreqCellReselectionInfo.p_Max ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->p_Max : not defined\n" ); + + if( sib2->intraFreqCellReselectionInfo.smtc) + LOG_I( RRC, "intraFreqCellReselectionInfo.smtc : %p\n", + sib2->intraFreqCellReselectionInfo.smtc ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->smtc : not defined\n" ); + + if( sib2->intraFreqCellReselectionInfo.ss_RSSI_Measurement) + LOG_I( RRC, "intraFreqCellReselectionInfo.ss_RSSI_Measurement : %p\n", + sib2->intraFreqCellReselectionInfo.ss_RSSI_Measurement ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->ss_RSSI_Measurement : not defined\n" ); + + if( sib2->intraFreqCellReselectionInfo.ssb_ToMeasure) + LOG_I( RRC, "intraFreqCellReselectionInfo.ssb_ToMeasure : %p\n", + sib2->intraFreqCellReselectionInfo.ssb_ToMeasure ); + else + LOG_I( RRC, "intraFreqCellReselectionInfo->ssb_ToMeasure : not defined\n" ); + + LOG_I( RRC, "intraFreqCellReselectionInfo.deriveSSB_IndexFromCell : %d\n", + sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell ); + +} + +void nr_dump_sib3( NR_SIB3_t *sib3 ) { +//intraFreqNeighCellList + if( sib3->intraFreqNeighCellList){ + LOG_I( RRC, "intraFreqNeighCellList : %p\n", + sib3->intraFreqNeighCellList ); + const int n = sib3->intraFreqNeighCellList->list.count; + for (int i = 0; i < n; ++i){ + LOG_I( RRC, "intraFreqNeighCellList->physCellId : %ld\n", + sib3->intraFreqNeighCellList->list.array[i]->physCellId ); + LOG_I( RRC, "intraFreqNeighCellList->q_OffsetCell : %ld\n", + sib3->intraFreqNeighCellList->list.array[i]->q_OffsetCell ); + + if( sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCell) + LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCell : %ld\n", + *sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCell ); + else + LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCell : not defined\n" ); + + if( sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCellSUL) + LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCellSUL : %ld\n", + *sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCellSUL ); + else + LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCellSUL : not defined\n" ); + + if( sib3->intraFreqNeighCellList->list.array[i]->q_QualMinOffsetCell) + LOG_I( RRC, "intraFreqNeighCellList->q_QualMinOffsetCell : %ld\n", + *sib3->intraFreqNeighCellList->list.array[i]->q_QualMinOffsetCell ); + else + LOG_I( RRC, "intraFreqNeighCellList->q_QualMinOffsetCell : not defined\n" ); + } + } else{ + LOG_I( RRC, "intraFreqCellReselectionInfo : not defined\n" ); + } + +//intraFreqBlackCellList + if( sib3->intraFreqBlackCellList){ + LOG_I( RRC, "intraFreqBlackCellList : %p\n", + sib3->intraFreqBlackCellList ); + const int n = sib3->intraFreqBlackCellList->list.count; + for (int i = 0; i < n; ++i){ + LOG_I( RRC, "intraFreqBlackCellList->start : %ld\n", + sib3->intraFreqBlackCellList->list.array[i]->start ); + + if( sib3->intraFreqBlackCellList->list.array[i]->range) + LOG_I( RRC, "intraFreqBlackCellList->range : %ld\n", + *sib3->intraFreqBlackCellList->list.array[i]->range ); + else + LOG_I( RRC, "intraFreqBlackCellList->range : not defined\n" ); + } + } else{ + LOG_I( RRC, "intraFreqBlackCellList : not defined\n" ); + } + +//lateNonCriticalExtension + if( sib3->lateNonCriticalExtension) + LOG_I( RRC, "lateNonCriticalExtension : %p\n", + sib3->lateNonCriticalExtension ); + else + LOG_I( RRC, "lateNonCriticalExtension : not defined\n" ); +} + +int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) { + NR_SystemInformation_t **si = &NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index]; + int new_sib = 0; + NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); + + // Dump contents + if ((*si)->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation || + (*si)->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r16) { + LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n", + (*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count ); + } else { + LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel16)\n" ); + return -1; + } + + for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) { + SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo; + typeandinfo = (*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i]; + + switch(typeandinfo->present) { + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&2) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=2; + //new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib2[gNB_index], &typeandinfo->choice.sib2, sizeof(NR_SIB2_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + nr_dump_sib2( NR_UE_rrc_inst[ctxt_pP->module_id].sib2[gNB_index] ); + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id ); + //TODO rrc_mac_config_req_ue + + // After SI is received, prepare RRCConnectionRequest + if (NR_UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option + if (AMF_MODE_ENABLED) { + rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index ); + } + + if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) { + LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id ); + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_SI_RECEIVED; +#if ENABLE_RAL + /* TODO { + MessageDef *message_ral_p = NULL; + rrc_ral_system_information_ind_t ral_si_ind; + message_ral_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_RAL_SYSTEM_INFORMATION_IND); + memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t)); + ral_si_ind.plmn_id.MCCdigit2 = '0'; + ral_si_ind.plmn_id.MCCdigit1 = '2'; + ral_si_ind.plmn_id.MNCdigit3 = '0'; + ral_si_ind.plmn_id.MCCdigit3 = '8'; + ral_si_ind.plmn_id.MNCdigit2 = '9'; + ral_si_ind.plmn_id.MNCdigit1 = '9'; + ral_si_ind.cell_id = 1; + ral_si_ind.dbm = 0; + //ral_si_ind.dbm = fifo_dump_emos_UE.PHY_measurements->rx_rssi_dBm[gNB_index]; + // TO DO + ral_si_ind.sinr = 0; + //ral_si_ind.sinr = fifo_dump_emos_UE.PHY_measurements->subband_cqi_dB[gNB_index][phy_vars_ue->lte_frame_parms.nb_antennas_rx][0]; + // TO DO + ral_si_ind.link_data_rate = 0; + memcpy (&message_ral_p->ittiMsg, (void *) &ral_si_ind, sizeof(rrc_ral_system_information_ind_t)); +#warning "ue_mod_idP ? for instance ?" + itti_send_msg_to_task (TASK_RAL_UE, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), message_ral_p); + }*/ +#endif + } + } + + break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&4) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=4; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib3[gNB_index], &typeandinfo->choice.sib3, sizeof(LTE_SystemInformationBlockType3_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB3 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + nr_dump_sib3( NR_UE_rrc_inst[ctxt_pP->module_id].sib3[gNB_index] ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&8) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=8; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib4[gNB_index], typeandinfo->choice.sib4, sizeof(NR_SIB4_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB4 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&16) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=16; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib5[gNB_index], typeandinfo->choice.sib5, sizeof(NR_SIB5_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + //dump_sib5(NR_UE_rrc_inst[ctxt_pP->module_id].sib5[gNB_index]); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&32) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=32; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib6[gNB_index], typeandinfo->choice.sib6, sizeof(NR_SIB6_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&64) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=64; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib7[gNB_index], typeandinfo->choice.sib7, sizeof(NR_SIB7_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB7 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&128) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=128; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib8[gNB_index], typeandinfo->choice.sib8, sizeof(NR_SIB8_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB8 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&256) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=256; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib9[gNB_index], typeandinfo->choice.sib9, sizeof(NR_SIB9_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&512) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=512; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib10[gNB_index], typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB10 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1024) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=1024; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib11[gNB_index], typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB11 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&2048) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=2048; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib12[gNB_index], typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&4096) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=4096; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib13[gNB_index], typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + //dump_sib13( NR_UE_rrc_inst[ctxt_pP->module_id].sib13[gNB_index] ); + // adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer + LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + // TODO rrc_mac_config_req_ue + } + break; + + case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&8192) == 0) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=8192; + new_sib=1; + memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib12[gNB_index], typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB14 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index ); + } + + break; + + default: + break; + } + if (new_sib == 1) { + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt++; + + if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count) + nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); + + LOG_I(NR_RRC,"SIStatus %x, SIcnt %d/%d\n", + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus, + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt, + sib1->si_SchedulingInfo->schedulingInfoList.list.count); + } + } + + //if (new_sib == 1) { + // NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt++; + + // if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->schedulingInfoList.list.count) + // rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); + + // LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", + // NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus, + // NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt, + // sib1->schedulingInfoList.list.count); + //} + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT); + return 0; +} + +int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t rsrq, const uint8_t rsrp ) { + NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); + LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); + const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; + for (int i = 0; i < n; ++i) { + NR_PLMN_Identity_t *PLMN_identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_IdentityList.list.array[0]; + int mccdigits = PLMN_identity->mcc->list.count; + int mncdigits = PLMN_identity->mnc.list.count; + + int mcc; + if (mccdigits == 2) { + mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; + } else { + mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + } + + int mnc; + if (mncdigits == 2) { + mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; + } else { + mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; + } + + LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc); + // search internal table for provider name + int plmn_ind = 0; + + while (plmn_data[plmn_ind].mcc > 0) { + if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { + LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); + break; + } + + plmn_ind++; + } + } + LOG_I( RRC, "TAC 0x%04x\n", + ((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->size == 2)?((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[0]<<8) + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[1]):0)); + LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, + nr_SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); + + LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", + BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity ), + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[0], + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[1], + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[2], + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.bits_unused); + //LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) ); + //LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) ); + //LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication ); + + //if (sib1->cellAccessRelatedInfo.csg_Identity) + // LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) ); + //else + // LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" ); + + LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo->q_RxLevMin ); + + if (sib1->cellSelectionInfo->q_RxLevMinOffset) + LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo->q_RxLevMinOffset ); + else + LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" ); + + //if (sib1->p_Max) + // LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max ); + //else + // LOG_I( RRC, "p_Max : not defined\n" ); + + //LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator ); + + if (sib1->si_SchedulingInfo->schedulingInfoList.list.count > 0) { + for (int i=0; isi_SchedulingInfo->schedulingInfoList.list.count; i++) { + LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->si_Periodicity,7)]); + + if (sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) { + char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32 + + for (int j=0; jsi_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) { + sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0]->type,11)] ); + } + + LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp ); + } else { + LOG_I( RRC, "mapping list %d is null\n", i ); + } + } + } else { + LOG_E( RRC, "siSchedulingInfoPeriod[0] : PROBLEM!!!\n" ); + return -1; + } + + if (sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon) { + //TODO + } + + LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_SchedulingInfo->si_WindowLength,8)] ); + //LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag ); + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIperiod = siPeriod_int[sib1->si_SchedulingInfo->schedulingInfoList.list.array[0]->si_Periodicity]; + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIwindowsize = siWindowLength_int[sib1->si_SchedulingInfo->si_WindowLength]; + LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", + ctxt_pP->module_id, gNB_index, ctxt_pP->module_id ); + //rrc_mac_config_req_ue + LOG_I(RRC,"Setting SIStatus bit 0 to 1\n"); + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus = 1; + //NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag; + + if (AMF_MODE_ENABLED) { + int cell_valid = 0; + + //if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { + /* Cell is not barred */ + int plmn; + int plmn_number; + plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; + + /* Compare requested PLMN and PLMNs from SIB1*/ + for (plmn = 0; plmn < plmn_number; plmn++) { + NR_PLMN_Identity_t *plmn_Identity; + plmn_Identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_IdentityList.list.array[0]; + + if ( + ( + (plmn_Identity->mcc == NULL) + || + ( + (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) && + (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) && + (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2])) + ) + ) + && + (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0])) + && + (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1])) + && + ( + ((NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2)) + || + (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2])) + ) + ) { + /* PLMN match, send a confirmation to NAS */ + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CELL_SELECTION_CNF); + NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS; + NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity); + NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode); + NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF; + NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq; + NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp; + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); + cell_valid = 1; + NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1; + break; + } + } + //} + + if (cell_valid == 0) { + /* Cell can not be used, ask PHY to try the next one */ + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, PHY_FIND_NEXT_CELL_REQ); + itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); + LOG_E(RRC, + "Synched with a cell, but PLMN doesn't match our SIM " + "(selected_plmn_identity %ld), the message PHY_FIND_NEXT_CELL_REQ " + "is sent but lost in current UE implementation!\n", + NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT ); + return 0; +} + +int nr_decode_BCCH_DLSCH_Message( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + uint8_t *const Sdu, + const uint8_t Sdu_len, + const uint8_t rsrq, + const uint8_t rsrp ) { + NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; + NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN ); + + if (((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received + (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) { + // to prevent memory bloating + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + return 0; + } + + nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR ); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message ); + } + + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_BCCH_DL_SCH_Message, + (void **)&bcch_message, + (const void *)Sdu, + Sdu_len ); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n", + ctxt_pP->module_id, + dec_rval.consumed ); + log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" ); + // free the memory + SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + return -1; + } + + if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) { + switch (bcch_message->message.choice.c1->present) { + case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: + if ((ctxt_pP->frame % 2) == 0) { + // even frame + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 0) { + NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index]; + memcpy( (void *)sib1, + (void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1, + sizeof(NR_SIB1_t) ); + LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id ); + nr_decode_SIB1( ctxt_pP, gNB_index, rsrq, rsrp ); + } + } + + break; + + case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: + if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) { + // SIB1 with schedulingInfoList is available + NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index]; + memcpy( si, + bcch_message->message.choice.c1->choice.systemInformation, + sizeof(NR_SystemInformation_t) ); + LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n", + ctxt_pP->module_id, + ctxt_pP->frame ); + nr_decode_SI( ctxt_pP, gNB_index ); + //if (nfapi_mode == 3) + //UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1; + } + + break; + + case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: + default: + break; + } + } + + if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) { + //if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) { + rrc_ue_generate_RRCSetupRequest(ctxt_pP, 0); + nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING ); + //} + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); + return 0; +} + +//----------------------------------------------------------------------------- +void +nr_rrc_ue_process_masterCellGroup( + const protocol_ctxt_t *const ctxt_pP, + uint8_t gNB_index, + OCTET_STRING_t *masterCellGroup +) +//----------------------------------------------------------------------------- +{ + NR_CellGroupConfig_t *cellGroupConfig = (NR_CellGroupConfig_t *)masterCellGroup; + if( cellGroupConfig->spCellConfig != NULL && cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){ + //TODO (perform Reconfiguration with sync according to 5.3.5.5.2) + //TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended) + } + + if( cellGroupConfig->rlc_BearerToReleaseList != NULL){ + //TODO (perform RLC bearer release as specified in 5.3.5.5.3) + } + + if( cellGroupConfig->rlc_BearerToAddModList != NULL){ + //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4) + } + + if( cellGroupConfig->mac_CellGroupConfig != NULL){ + //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) + } + + if( cellGroupConfig->sCellToReleaseList != NULL){ + //TODO (perform SCell release as specified in 5.3.5.5.8) + } + + if( cellGroupConfig->spCellConfig != NULL){ + if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig, + sizeof(struct NR_SpCellConfig)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig; + } + //TODO (configure the SpCell as specified in 5.3.5.5.7) + } + + if( cellGroupConfig->sCellToAddModList != NULL){ + //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) + } + + if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ + //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) + } + + if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ + //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) + } +} + +/*--------------------------------------------------*/ +static void rrc_ue_generate_RRCSetupComplete( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id){ + + uint8_t buffer[100]; + uint8_t size; + const char *nas_msg; + int nas_msg_length; + if (AMF_MODE_ENABLED) { +#if ITTI_SIM + as_nas_info_t initialNasMsg; + generateRegistrationRequest(&initialNasMsg); + nas_msg = (char*)initialNasMsg.data; + nas_msg_length = initialNasMsg.length; +#else + nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; + nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; +#endif + } else { + nas_msg = nr_nas_attach_req_imsi; + nas_msg_length = sizeof(nr_nas_attach_req_imsi); + } + size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg); + LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); + LOG_D(RLC, + "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", + ctxt_pP->frame, ctxt_pP->module_id+NB_RN_INST, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH); + // ctxt_pP_local.rnti = ctxt_pP->rnti; + rrc_data_req_ue( + ctxt_pP, + DCCH, + nr_rrc_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE, TASK_RRC_GNB_SIM, size); + memcpy (message_buffer, buffer, size); + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); + UE_RRC_DCCH_DATA_IND (message_p).rbid = 1; + UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + UE_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); +#endif +} + +int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){ + NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; + asn_dec_rval_t dec_rval; + int rval=0; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN); + // LOG_D(RRC,"[UE %d] Decoding DL-CCCH message (%d bytes), State %d\n",ue_mod_idP,Srb_info->Rx_buffer.payload_size, + // NR_UE_rrc_inst[ue_mod_idP].Info[gNB_index].State); + dec_rval = uper_decode(NULL, + &asn_DEF_NR_DL_CCCH_Message, + (void **)&dl_ccch_msg, + (uint8_t *)Srb_info->Rx_buffer.Payload, + 100,0,0); + + // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg); + // } + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) { + LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); + return -1; + } + + if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_SI_RECEIVED) { + switch (dl_ccch_msg->message.choice.c1->present) { + case NR_DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = 0; + break; + + case NR_DL_CCCH_MessageType__c1_PR_rrcReject: + LOG_I(NR_RRC, + "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = 0; + break; + + case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: + LOG_I(NR_RRC, + "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ctxt_pP->rnti); + + // Get configuration + // Release T300 timer + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0; + + nr_rrc_ue_process_masterCellGroup( + ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup); + nr_sa_rrc_ue_process_radioBearerConfig( + ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); + nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); + nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti; + rrc_ue_generate_RRCSetupComplete( + ctxt_pP, + gNB_index, + dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, + NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); + rval = 0; + break; + + default: + LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n", + ctxt_pP->module_id, + ctxt_pP->frame); + rval = -1; + break; + } + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT); + return rval; +} + +/*brief decode SIB1 message*/ +int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) { + + NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; + + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_BCCH_DL_SCH_Message, + (void **)&bcch_message, + (const void *)bufferP, + buffer_len); + + if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { + LOG_D(RRC,"NR_BCCH_DL_SCH decode error\n"); + SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 ); + return -1; + } + else { + NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index]; + if(sib1 != NULL){ + SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 ); + } + sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + if (*(int64_t*)sib1 != 1) { + LOG_I(RRC, "SIB1 decoded\n"); + if( g_log->log_component[RRC].level >= OAILOG_DEBUG ) + xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1); + } + else + LOG_E(PHY, "sib1 is starting by 8 times 0\n"); + } + + return 0; +} + // from NR SRB3 int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message( - const module_id_t module_id, - const uint8_t gNB_index, - const uint8_t *bufferP, - const uint32_t buffer_len ){ - // uper_decode by nr R15 rrc_connection_reconfiguration - - int32_t i; - NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL; + const module_id_t module_id, + const uint8_t gNB_index, + const uint8_t *bufferP, + const uint32_t buffer_len ){ + // uper_decode by nr R15 rrc_connection_reconfiguration + + int32_t i; + NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL; + MessageDef *msg_p; - asn_dec_rval_t dec_rval = uper_decode( NULL, - &asn_DEF_NR_DL_DCCH_Message, - (void**)&nr_dl_dcch_msg, - (uint8_t *)bufferP, - buffer_len, 0, 0); + asn_dec_rval_t dec_rval = uper_decode( NULL, + &asn_DEF_NR_DL_DCCH_Message, + (void**)&nr_dl_dcch_msg, + (uint8_t *)bufferP, + buffer_len, 0, 0); - if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { + if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) { + for (i=0; imessage.present){ + case NR_DL_DCCH_MessageType_PR_c1: + switch(nr_dl_dcch_msg->message.choice.c1->present){ + case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: + nr_rrc_ue_process_rrcReconfiguration(module_id,nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration); + break; - printf("\n"); - // free the memory - SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); - return -1; - } - - if(nr_dl_dcch_msg != NULL){ - switch(nr_dl_dcch_msg->message.present){ - case NR_DL_DCCH_MessageType_PR_c1: - - switch(nr_dl_dcch_msg->message.choice.c1->present){ - case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: - nr_rrc_ue_process_rrcReconfiguration(nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration); - break; - - case NR_DL_DCCH_MessageType__c1_PR_NOTHING: - case NR_DL_DCCH_MessageType__c1_PR_rrcResume: - case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: - case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: - case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: - case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: - case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: - case NR_DL_DCCH_MessageType__c1_PR_counterCheck: - case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: - case NR_DL_DCCH_MessageType__c1_PR_spare7: - case NR_DL_DCCH_MessageType__c1_PR_spare6: - case NR_DL_DCCH_MessageType__c1_PR_spare5: - case NR_DL_DCCH_MessageType__c1_PR_spare4: - case NR_DL_DCCH_MessageType__c1_PR_spare3: - case NR_DL_DCCH_MessageType__c1_PR_spare2: - case NR_DL_DCCH_MessageType__c1_PR_spare1: - default: - // not supported or unused - break; - } - break; - case NR_DL_DCCH_MessageType_PR_NOTHING: - case NR_DL_DCCH_MessageType_PR_messageClassExtension: - default: - // not supported or unused - break; + case NR_DL_DCCH_MessageType__c1_PR_NOTHING: + case NR_DL_DCCH_MessageType__c1_PR_rrcResume: + case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); + if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && + (nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ + nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; + nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; + } + itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: + case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: + case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + case NR_DL_DCCH_MessageType__c1_PR_counterCheck: + case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: + case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: + case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: + case NR_DL_DCCH_MessageType__c1_PR_spare3: + case NR_DL_DCCH_MessageType__c1_PR_spare2: + case NR_DL_DCCH_MessageType__c1_PR_spare1: + default: + // not supported or unused + break; } - - // release memory allocation - SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); - }else{ - // log.. + break; + case NR_DL_DCCH_MessageType_PR_NOTHING: + case NR_DL_DCCH_MessageType_PR_messageClassExtension: + default: + // not supported or unused + break; + } + + // release memory allocation + SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 ); + }else{ + // log.. + } + + return 0; +} + + +//----------------------------------------------------------------------------- +void +nr_rrc_ue_process_securityModeCommand( + const protocol_ctxt_t *const ctxt_pP, + NR_SecurityModeCommand_t *const securityModeCommand, + const uint8_t gNB_index +) +//----------------------------------------------------------------------------- +{ + asn_enc_rval_t enc_rval; + NR_UL_DCCH_Message_t ul_dcch_msg; + uint8_t buffer[200]; + int i, securityMode; + LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index); + + switch (securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) { + case NR_CipheringAlgorithm_nea0: + LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea0\n", + ctxt_pP->module_id); + securityMode= NR_CipheringAlgorithm_nea0; + break; + + case NR_CipheringAlgorithm_nea1: + LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea1\n",ctxt_pP->module_id); + securityMode= NR_CipheringAlgorithm_nea1; + break; + + case NR_CipheringAlgorithm_nea2: + LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea2\n", + ctxt_pP->module_id); + securityMode = NR_CipheringAlgorithm_nea2; + break; + + default: + LOG_I(NR_RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id); + securityMode = NR_CipheringAlgorithm_spare1; + break; + } + + switch (*securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) { + case NR_IntegrityProtAlgorithm_nia1: + LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia1\n",ctxt_pP->module_id); + securityMode |= 1 << 5; + break; + + case NR_IntegrityProtAlgorithm_nia2: + LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id); + securityMode |= 1 << 6; + break; + + default: + LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id); + securityMode |= 0x70 ; + break; + } + + LOG_D(NR_RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode); + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = + securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm; + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = + *securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm; + memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t)); + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = calloc(1, sizeof(*ul_dcch_msg.message.choice.c1)); + + if (securityMode >= NO_SECURITY_MODE) { + LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n"); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; + } else { + LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n"); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure; + } + + uint8_t *kRRCenc = NULL; + uint8_t *kUPenc = NULL; + uint8_t *kRRCint = NULL; + pdcp_t *pdcp_p = NULL; + hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; + hashtable_rc_t h_rc; + key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, + ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); + h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p); + + if (h_rc == HASH_TABLE_OK) { + LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key); + LOG_D(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x" + "%02x%02x%02x%02x\n", + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27], + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]); + derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); + derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); + derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); + + if (securityMode != 0xff) { + pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm + | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), + kRRCenc, kRRCint, kUPenc); + } else { + LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", + securityMode); + } + } else { + LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key); + } + + if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) { + ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t)); + ul_dcch_msg.message.choice.c1->choice.securityModeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; + ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete; + ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_IEs_t)); + ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL; + LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n", + ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index, securityModeCommand->rrc_TransactionIdentifier); + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, + NULL, + (void *)&ul_dcch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); + } + + LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + + for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) { + LOG_T(NR_RRC, "%02x.", buffer[i]); } - return 0; + LOG_T(NR_RRC, "\n"); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, + (enc_rval.encoded + 7) / 8); + memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); + + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); +#else + rrc_data_req ( + ctxt_pP, + DCCH, + nr_rrc_mui++, + SDU_CONFIRM_NO, + (enc_rval.encoded + 7) / 8, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif + } else + LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", + securityModeCommand->criticalExtensions.present); +} + +//----------------------------------------------------------------------------- +void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) { + uint8_t i=0,rv[6]; + + if(NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) { + // Get RRCConnectionRequest, fill random for now + // Generate random byte stream for contention resolution + for (i=0; i<6; i++) { +#ifdef SMBV + // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed + rv[i]=i; +#else + rv[i]=taus()&0xff; +#endif + LOG_T(NR_RRC,"%x.",rv[i]); + } + + LOG_T(NR_RRC,"\n"); + NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size = + do_RRCSetupRequest( + ctxt_pP->module_id, + (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, + rv); + LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %d)\n", + ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); + + for (i=0; imodule_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) { + LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]); + } + + LOG_T(NR_RRC,"\n"); + /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff; + UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */ + +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, + NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, + NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND); + GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); +#endif + } +} + +//----------------------------------------------------------------------------- +int32_t +nr_rrc_ue_establish_srb1( + module_id_t ue_mod_idP, + frame_t frameP, + uint8_t gNB_index, + NR_SRB_ToAddMod_t *SRB_config +) +//----------------------------------------------------------------------------- +{ + // add descriptor from RRC PDU + NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Active = 1; + NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG + NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Srb_info.Srb_id = 1; + LOG_I(NR_RRC, "[UE %d], CONFIG_SRB1 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH, gNB_index); + return(0); +} + +//----------------------------------------------------------------------------- +int32_t +nr_rrc_ue_establish_srb2( + module_id_t ue_mod_idP, + frame_t frameP, + uint8_t gNB_index, + NR_SRB_ToAddMod_t *SRB_config +) +//----------------------------------------------------------------------------- +{ + // add descriptor from RRC PDU + NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Active = 1; + NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Status = RADIO_CONFIG_OK;//RADIO CFG + NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Srb_info.Srb_id = 2; + LOG_I(NR_RRC, "[UE %d], CONFIG_SRB2 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH1, gNB_index); + return(0); +} + +//----------------------------------------------------------------------------- +int32_t +nr_rrc_ue_establish_drb( + module_id_t ue_mod_idP, + frame_t frameP, + uint8_t gNB_index, + NR_DRB_ToAddMod_t *DRB_config +) +//----------------------------------------------------------------------------- +{ + // add descriptor from RRC PDU + int oip_ifup = 0, ip_addr_offset3 = 0, ip_addr_offset4 = 0; + /* avoid gcc warnings */ + (void)oip_ifup; + (void)ip_addr_offset3; + (void)ip_addr_offset4; + LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n", + ue_mod_idP, frameP, DRB_config->drb_Identity); + + if(!AMF_MODE_ENABLED) { + ip_addr_offset3 = 0; + ip_addr_offset4 = 1; + LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP, + ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1); + oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1, // interface_id + UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet + ip_addr_offset4+ue_mod_idP+1, // fourth_octet + "oip"); // interface suffix (when using kernel module) + + if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB + LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n", + ue_mod_idP, + ip_addr_offset3+ue_mod_idP, + (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity)); + rb_conf_ipv4(0,//add + ue_mod_idP,//cx align with the UE index + ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index + (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb + 0,//dscp + ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr + ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr + LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index); + } + } + + return(0); +} + +//----------------------------------------------------------------------------- +void +nr_rrc_ue_process_measConfig( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + NR_MeasConfig_t *const measConfig +) +//----------------------------------------------------------------------------- +{ + int i; + long ind; + NR_MeasObjectToAddMod_t *measObj = NULL; + NR_ReportConfigToAddMod_t *reportConfig = NULL; + + if (measConfig->measObjectToRemoveList != NULL) { + for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) { + ind = *measConfig->measObjectToRemoveList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]); + } + } + + if (measConfig->measObjectToAddModList != NULL) { + LOG_I(NR_RRC, "Measurement Object List is present\n"); + for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) { + measObj = measConfig->measObjectToAddModList->list.array[i]; + ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; + + if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) { + LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1], + (char *)measObj, + sizeof(NR_MeasObjectToAddMod_t)); + } else { + LOG_I(NR_RRC, "Adding measurement object %ld\n", ind); + + if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) { + NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj; + } + } + } + + LOG_I(NR_RRC, "call rrc_mac_config_req \n"); + // rrc_mac_config_req_ue + } + + if (measConfig->reportConfigToRemoveList != NULL) { + for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) { + ind = *measConfig->reportConfigToRemoveList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]); + } + } + + if (measConfig->reportConfigToAddModList != NULL) { + LOG_I(NR_RRC,"Report Configuration List is present\n"); + for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) { + ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; + reportConfig = measConfig->reportConfigToAddModList->list.array[i]; + + if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) { + LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1], + (char *)measConfig->reportConfigToAddModList->list.array[i], + sizeof(NR_ReportConfigToAddMod_t)); + } else { + LOG_D(NR_RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]); + if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) { + NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; + } + } + } + } + + if (measConfig->measIdToRemoveList != NULL) { + for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) { + ind = *measConfig->measIdToRemoveList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]); + } + } + + if (measConfig->measIdToAddModList != NULL) { + for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) { + ind = measConfig->measIdToAddModList->list.array[i]->measId; + + if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) { + LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1], + (char *)measConfig->measIdToAddModList->list.array[i], + sizeof(NR_MeasIdToAddMod_t)); + } else { + LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]); + NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; + } + } + } + + if (measConfig->quantityConfig != NULL) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) { + LOG_D(NR_RRC,"Modifying Quantity Configuration \n"); + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index], + (char *)measConfig->quantityConfig, + sizeof(NR_QuantityConfig_t)); + } else { + LOG_D(NR_RRC, "Adding Quantity configuration\n"); + NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig; + } + } + + if (measConfig->measGapConfig != NULL) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) { + memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index], + (char *)measConfig->measGapConfig, + sizeof(NR_MeasGapConfig_t)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig; + } + } + + if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) { + NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP; + } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) { + NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP; + } +} + +//----------------------------------------------------------------------------- +void +nr_sa_rrc_ue_process_radioBearerConfig( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t gNB_index, + NR_RadioBearerConfig_t *const radioBearerConfig +) +//----------------------------------------------------------------------------- +{ + long SRB_id, DRB_id; + int i, cnt; + + if( radioBearerConfig->srb3_ToRelease != NULL){ + if( *radioBearerConfig->srb3_ToRelease == TRUE){ + //TODO (release the PDCP entity and the srb-Identity of the SRB3.) + } + } + + if (radioBearerConfig->srb_ToAddModList != NULL) { + if (radioBearerConfig->securityConfig != NULL) { + if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) { + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = + radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm; + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = + *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm; + } + } + + uint8_t *kRRCenc = NULL; + uint8_t *kRRCint = NULL; + derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc); + derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint); + // Refresh SRBs + // nr_rrc_pdcp_config_asn1_req(ctxt_pP, + // radioBearerConfig->srb_ToAddModList, + // NULL, + // NULL, + // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | + // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), + // kRRCenc, + // kRRCint, + // NULL, + // NULL, + // NULL, + // NULL); + // Refresh SRBs + // nr_rrc_rlc_config_asn1_req(ctxt_pP, + // radioBearerConfig->srb_ToAddModList, + // NULL, + // NULL, + // NULL, + // NULL + // ); + + for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) { + SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity; + LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id); + if (SRB_id == 1) { + if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index], + radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; + nr_rrc_ue_establish_srb1(ctxt_pP->module_id, + ctxt_pP->frame, + gNB_index, + radioBearerConfig->srb_ToAddModList->list.array[cnt]); + + LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + // rrc_mac_config_req_ue + } + } else { + if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index], + radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t)); + } else { + NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt]; + nr_rrc_ue_establish_srb2(ctxt_pP->module_id, + ctxt_pP->frame, + gNB_index, + radioBearerConfig->srb_ToAddModList->list.array[cnt]); + + LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n", + ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id); + // rrc_mac_config_req_ue + } + } // srb2 + } + } // srb_ToAddModList + + // Establish DRBs if present + if (radioBearerConfig->drb_ToAddModList != NULL) { + if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) && + (radioBearerConfig->drb_ToAddModList->list.count >= 1)) { + NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); + *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity; + } + + for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) { + DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity; + if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) { + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1], + radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t)); + } else { + LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]); + NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt]; + } + } + + uint8_t *kUPenc = NULL; + derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc); + MSC_LOG_TX_MESSAGE( + MSC_RRC_UE, + MSC_PDCP_UE, + NULL, + 0, + MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->rnti, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | + (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4)); + + // Refresh DRBs + // nr_rrc_pdcp_config_asn1_req(ctxt_pP, + // NULL, + // radioBearerConfig->drb_ToAddModList, + // NULL, + // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | + // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), + // NULL, + // NULL, + // kUPenc, + // NULL, + // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, + // NULL); + // Refresh DRBs + // nr_rrc_rlc_config_asn1_req(ctxt_pP, + // NULL, + // radioBearerConfig->drb_ToAddModList, + // NULL, + // NULL, + // NULL + // ); + } // drb_ToAddModList + + if (radioBearerConfig->drb_ToReleaseList != NULL) { + for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) { + DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i]; + free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]); + } + } + + NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED; + LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index); +} + +//----------------------------------------------------------------------------- +void +rrc_ue_process_rrcReconfiguration( + const protocol_ctxt_t *const ctxt_pP, + NR_RRCReconfiguration_t *rrcReconfiguration, + uint8_t gNB_index +) +//----------------------------------------------------------------------------- +{ + LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n", + ctxt_pP->module_id, ctxt_pP->frame, gNB_index); + + NR_RRCReconfiguration_IEs_t *ie = NULL; + + if (rrcReconfiguration->criticalExtensions.present + == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) { + ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration; + if (ie->measConfig != NULL) { + LOG_I(NR_RRC, "Measurement Configuration is present\n"); + nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig); + } + + if (ie->radioBearerConfig != NULL) { + LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); + nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); + } + + /* Check if there is dedicated NAS information to forward to NAS */ + if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) { + int list_count; + uint32_t pdu_length; + uint8_t *pdu_buffer; + MessageDef *msg_p; + + for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) { + pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size; + pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf; +#ifdef ITTI_SIM + uint8_t msg_type = 0; + if((pdu_buffer + 1) != NULL){ + if (*(pdu_buffer + 1) > 0 ) { + if((pdu_buffer + 9) != NULL){ + msg_type = *(pdu_buffer + 9); + } else { + LOG_W(NR_RRC, "[UE] Received invalid downlink message\n"); + return; + } + } else { + if((pdu_buffer + 2) != NULL){ + msg_type = *(pdu_buffer + 2); + } else { + LOG_W(NR_RRC, "[UE] Received invalid downlink message\n"); + return; + } + } + } + if(msg_type == REGISTRATION_ACCEPT){ + LOG_I(NR_RRC, "[UE] Received REGISTRATION ACCEPT message\n"); + } +#endif + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF); + NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; + NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); + } + + free (ie->nonCriticalExtension->dedicatedNAS_MessageList); + } + } +} + +//----------------------------------------------------------------------------- +void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) { + uint8_t buffer[32], size; + size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, Transaction_id); + LOG_I(NR_RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, gNB_index); + LOG_D(RLC, + "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n", + ctxt_pP->frame, + UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), + size, + gNB_index, + nr_rrc_mui, + UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), + DCCH); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size); + memcpy (message_buffer, buffer, size); + + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); + UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + UE_RRC_DCCH_DATA_IND (message_p).size = size; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); + +#else + rrc_data_req_ue ( + ctxt_pP, + DCCH, + nr_rrc_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif } + +// from NR SRB1 +//----------------------------------------------------------------------------- +int +nr_rrc_ue_decode_dcch( + const protocol_ctxt_t *const ctxt_pP, + const srb_id_t Srb_id, + const uint8_t *const Buffer, + const uint8_t gNB_indexP +) +//----------------------------------------------------------------------------- +{ + asn_dec_rval_t dec_rval; + NR_DL_DCCH_Message_t *dl_dcch_msg = NULL; + MessageDef *msg_p; + + if (Srb_id != 1) { + LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", + ctxt_pP->module_id, ctxt_pP->frame, Srb_id); + return -1; + } else { + LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id); + } + + LOG_D(NR_RRC, "Decoding DL-DCCH Message\n"); + dec_rval = uper_decode( NULL, + &asn_DEF_NR_DL_DCCH_Message, + (void **)&dl_dcch_msg, + Buffer, + RRC_BUF_SIZE, + 0, + 0); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed); + return -1; + } + + // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg); + // } + + if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) { + switch (dl_dcch_msg->message.choice.c1->present) { + case NR_DL_DCCH_MessageType__c1_PR_NOTHING: + LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n"); + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: + { + rrc_ue_process_rrcReconfiguration(ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, + gNB_indexP); + nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP, + gNB_indexP, + dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); + + if (first_rrcreconfigurationcomplete == 0) { + first_rrcreconfigurationcomplete = 1; +#ifdef ITTI_SIM + if (AMF_MODE_ENABLED) { + as_nas_info_t initialNasMsg; + memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); + generateRegistrationComplete(&initialNasMsg, NULL); + if(initialNasMsg.length > 0){ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); + LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); + } + as_nas_info_t pduEstablishMsg; + memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); + generatePduSessionEstablishRequest(&pduEstablishMsg); + if(initialNasMsg.length > 0){ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); + LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); + } + } +#endif + } + } + break; + + case NR_DL_DCCH_MessageType__c1_PR_rrcResume: + case NR_DL_DCCH_MessageType__c1_PR_rrcRelease: + LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", + ctxt_pP->module_id, gNB_indexP); + + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND); + + if((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) && + (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){ + dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5; + dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType = + NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency; + } + + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); + break; + case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", + ctxt_pP->module_id,gNB_indexP); + nr_rrc_ue_process_ueCapabilityEnquiry( + ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, + gNB_indexP); + break; + case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment: + LOG_I(NR_RRC, + "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n", + ctxt_pP->module_id, + ctxt_pP->frame); + nr_rrc_ue_generate_rrcReestablishmentComplete( + ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.rrcReestablishment, + gNB_indexP); + break; + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: + { + NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer; + + if (dlInformationTransfer->criticalExtensions.present + == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) { + /* This message hold a dedicated info NAS payload, forward it to NAS */ + NR_DedicatedNAS_Message_t *dedicatedNAS_Message = + dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message; + uint32_t pdu_length; + uint8_t *pdu_buffer; + pdu_length = dedicatedNAS_Message->size; + pdu_buffer = dedicatedNAS_Message->buf; +#ifdef ITTI_SIM + LOG_I(NR_RRC, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", ctxt_pP->module_id, messages_info[NAS_DOWNLINK_DATA_IND].name, + ctxt_pP->module_id, pdu_length, pdu_buffer); + as_nas_info_t initialNasMsg; + uint8_t msg_type = 0; + memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); + if((pdu_buffer + 1) != NULL){ + if (*(pdu_buffer + 1) > 0 ) { + msg_type = *(pdu_buffer + 9); + } else { + msg_type = *(pdu_buffer + 2); + } + } + if((pdu_buffer + 2) == NULL){ + LOG_W(NR_RRC, "[UE] Received invalid downlink message\n"); + return 0; + } + + switch(msg_type){ + case FGS_IDENTITY_REQUEST: + generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3)); + break; + case FGS_AUTHENTICATION_REQUEST: + generateAuthenticationResp(&initialNasMsg, pdu_buffer); + break; + case FGS_SECURITY_MODE_COMMAND: + generateSecurityModeComplete(&initialNasMsg); + break; + default: + LOG_W(NR_RRC,"unknow message type %d\n",msg_type); + break; + } + if(initialNasMsg.length > 0){ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)initialNasMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = initialNasMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); + LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message\n"); + } +#else + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND); + NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ? + NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = pdu_length; + NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = pdu_buffer; + itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); +#endif + } + } + + break; + case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand: + case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16: + case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16: + case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16: + case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16: + case NR_DL_DCCH_MessageType__c1_PR_spare3: + case NR_DL_DCCH_MessageType__c1_PR_spare2: + case NR_DL_DCCH_MessageType__c1_PR_spare1: + case NR_DL_DCCH_MessageType__c1_PR_counterCheck: + break; + case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand: + LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", + ctxt_pP->module_id, gNB_indexP); + nr_rrc_ue_process_securityModeCommand( + ctxt_pP, + dl_dcch_msg->message.choice.c1->choice.securityModeCommand, + gNB_indexP); + + break; + } + } + return 0; +} + +//----------------------------------------------------------------------------- +void *rrc_nrue_task( void *args_p ) { + MessageDef *msg_p; + instance_t instance; + unsigned int ue_mod_id; + int result; + NR_SRB_INFO *srb_info_p; + protocol_ctxt_t ctxt; + itti_mark_task_ready (TASK_RRC_NRUE); + + while(1) { + // Wait for a message + itti_receive_msg (TASK_RRC_NRUE, &msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); + ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting RRC thread\n"); + itti_exit_task (); + break; + + case MESSAGE_TEST: + LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); + break; + + case NR_RRC_MAC_BCCH_DATA_IND: + LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), + NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); + // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); + nr_decode_BCCH_DLSCH_Message (&ctxt, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq, + NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); + + case NR_RRC_MAC_CCCH_DATA_IND: + LOG_D(NR_RRC, "[UE %d] RNTI %x Received %s: frameP %d, gNB %d\n", + ue_mod_id, + NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, + ITTI_MSG_NAME (msg_p), + NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, + NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); + srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index]; + memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu, + NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size); + srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0); + // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); + nr_rrc_ue_decode_ccch (&ctxt, + srb_info_p, + NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index); + break; + + /* PDCP messages */ + case NR_RRC_DCCH_DATA_IND: + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, NR_RRC_DCCH_DATA_IND (msg_p).module_id, GNB_FLAG_NO, NR_RRC_DCCH_DATA_IND (msg_p).rnti, NR_RRC_DCCH_DATA_IND (msg_p).frame, 0,NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); + LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n", + NR_RRC_DCCH_DATA_IND (msg_p).module_id, + ITTI_MSG_NAME (msg_p), + NR_RRC_DCCH_DATA_IND (msg_p).frame, + NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); + LOG_D(NR_RRC, PROTOCOL_RRC_CTXT_UE_FMT"Received %s DCCH %d, gNB %d\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), + ITTI_MSG_NAME (msg_p), + NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); + nr_rrc_ue_decode_dcch ( + &ctxt, + NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, + NR_RRC_DCCH_DATA_IND (msg_p).sdu_p, + NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); + break; + + case NAS_UPLINK_DATA_REQ: { + uint32_t length; + uint8_t *buffer; + LOG_I(NR_RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NAS_UPLINK_DATA_REQ (msg_p).UEid); + /* Create message for PDCP (ULInformationTransfer_t) */ + length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); + /* Transfer data to PDCP */ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length); + memcpy (message_buffer, buffer, length); + + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); + if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) + UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + else + UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH1; + UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + UE_RRC_DCCH_DATA_IND (message_p).size = length; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt.instance, message_p); + +#else + // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) + if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) { + rrc_data_req_ue (&ctxt, + DCCH, + nr_rrc_mui++, + SDU_CONFIRM_NO, + length, buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } else { + rrc_data_req_ue (&ctxt, + DCCH1, + nr_rrc_mui++, + SDU_CONFIRM_NO, + length, buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } +#endif + break; + } + + default: + LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); + break; + } + LOG_I(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id)); + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + msg_p = NULL; + } +} +void nr_rrc_ue_process_sidelink_radioResourceConfig( + module_id_t Mod_idP, + uint8_t gNB_index, + NR_SetupRelease_SL_ConfigDedicatedNR_r16_t *sl_ConfigDedicatedNR +) +{ + //process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED) + if (sl_ConfigDedicatedNR != NULL) { + switch (sl_ConfigDedicatedNR->present){ + case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_setup: + //TODO + break; + case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_release: + break; + case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_NOTHING: + break; + default: + break; + } + } +} + +//----------------------------------------------------------------------------- +void +nr_rrc_ue_process_ueCapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + NR_UECapabilityEnquiry_t *UECapabilityEnquiry, + uint8_t gNB_index +) +//----------------------------------------------------------------------------- +{ + asn_enc_rval_t enc_rval; + NR_UL_DCCH_Message_t ul_dcch_msg; + NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; + uint8_t buffer[200]; + int i; + LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + gNB_index); + memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t)); + memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t)); + ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1)); + ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation)); + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; + ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; + NR_UE_NR_Capability_t* UE_Capability_nr; + UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t)); + NR_BandNR_t *nr_bandnr; + nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t)); + nr_bandnr->bandNR = 1; + ASN_SEQUENCE_ADD( + &UE_Capability_nr->rf_Parameters.supportedBandListNR.list, + nr_bandnr); + OAI_NR_UECapability_t *UECap; + UECap = CALLOC(1,sizeof(OAI_NR_UECapability_t)); + UECap->UE_NR_Capability = UE_Capability_nr; + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr); + } + + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability, + NULL, + (void *)UE_Capability_nr, + &UECap->sdu[0], + MAX_UE_NR_CAPABILITY_SIZE); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + UECap->sdu_size = (enc_rval.encoded + 7) / 8; + LOG_I(PHY, "[RRC]UE NR Capability encoded, %d bytes (%zd bits)\n", + UECap->sdu_size, enc_rval.encoded + 7); + + NR_UE_rrc_inst[ctxt_pP->module_id].UECap = UECap; + NR_UE_rrc_inst[ctxt_pP->module_id].UECapability = UECap->sdu; + NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size = UECap->sdu_size; + OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, + (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability, + NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size); + // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability; + // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size; + AssertFatal(UECapabilityEnquiry->criticalExtensions.present == NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry, + "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", + UECapabilityEnquiry->criticalExtensions.present,NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry); + + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation; + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs)); + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList = CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList)); + ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0; + + for (i=0; icriticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.count; i++) { + if (UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type + == NR_RAT_Type_nr) { + ASN_SEQUENCE_ADD( + &ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list, + &ue_CapabilityRAT_Container); + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); + } + + LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, + (enc_rval.encoded + 7) / 8); + memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); + + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); + GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); +#else + rrc_data_req_ue ( + ctxt_pP, + DCCH, + nr_rrc_mui++, + SDU_CONFIRM_NO, + (enc_rval.encoded + 7) / 8, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); +#endif + } + } +} + +//----------------------------------------------------------------------------- +void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) +{ + NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size = + do_RRCReestablishmentRequest( + ctxt_pP->module_id, + (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, 1); + LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCReestablishmentRequest (bytes %d, gNB %d)\n", + ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); + + for (int i=0; imodule_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) { + LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]); + } + + LOG_T(NR_RRC,"\n"); + +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, + NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size); + memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, + NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size); + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND); + UE_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; + UE_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); +#endif +} + +void +nr_rrc_ue_generate_rrcReestablishmentComplete( + const protocol_ctxt_t *const ctxt_pP, + NR_RRCReestablishment_t *rrcReestablishment, + uint8_t gNB_index +) +//----------------------------------------------------------------------------- +{ + uint32_t length; + uint8_t buffer[100]; + length = do_RRCReestablishmentComplete(buffer, rrcReestablishment->rrc_TransactionIdentifier); + LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n", + ctxt_pP->module_id,ctxt_pP->frame, length, gNB_index); +#ifdef ITTI_SIM + MessageDef *message_p; + uint8_t *message_buffer; + message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length); + memcpy (message_buffer, buffer, length); + + message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); + UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; + UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; + UE_RRC_DCCH_DATA_IND (message_p).size = length; + itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); + +#endif +} diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index 6481fb0cea..52bd6c564a 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -39,7 +39,6 @@ #include "platform_types.h" -#include "NR_MAC_UE/mac.h" #include "NR_MAC_COMMON/nr_mac.h" #include "rrc_list.h" #include "NR_asn_constant.h" @@ -51,10 +50,18 @@ #include "NR_asn_constant.h" #include "NR_SchedulingRequestToAddMod.h" #include "NR_MIB.h" +#include "NR_SIB1.h" #include "NR_BCCH-BCH-Message.h" #include "NR_DL-DCCH-Message.h" +#include "../NR/nr_rrc_defs.h" #define NB_NR_UE_INST 1 +#define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE +#define NB_SIG_CNX_UE 2 //MAX_MANAGED_RG_PER_MOBILE + +#define MAX_MEAS_OBJ 6 +#define MAX_MEAS_CONFIG 6 +#define MAX_MEAS_ID 6 typedef uint32_t channel_t; @@ -63,14 +70,67 @@ typedef enum { nr_RadioBearerConfigX_r15=1 } nsa_message_t; +#define MAX_UE_NR_CAPABILITY_SIZE 255 +typedef struct OAI_NR_UECapability_s { + uint8_t sdu[MAX_UE_NR_CAPABILITY_SIZE]; + uint8_t sdu_size; + NR_UE_NR_Capability_t *UE_NR_Capability; +} OAI_NR_UECapability_t; + typedef struct NR_UE_RRC_INST_s { NR_MeasConfig_t *meas_config; NR_CellGroupConfig_t *cell_group_config; NR_RadioBearerConfig_t *radio_bearer_config; - + + NR_MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; + NR_ReportConfigToAddMod_t *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; + NR_QuantityConfig_t *QuantityConfig[NB_CNX_UE]; + NR_MeasIdToAddMod_t *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + NR_MeasGapConfig_t *measGapConfig[NB_CNX_UE]; + NR_RSRP_Range_t s_measure; + NR_SRB_ToAddMod_t *SRB1_config[NB_CNX_UE]; + NR_SRB_ToAddMod_t *SRB2_config[NB_CNX_UE]; + NR_DRB_ToAddMod_t *DRB_config[NB_CNX_UE][8]; + rb_id_t *defaultDRB; // remember the ID of the default DRB + + NR_SRB_INFO Srb0[NB_SIG_CNX_UE]; + NR_SRB_INFO_TABLE_ENTRY Srb1[NB_CNX_UE]; + NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE]; + + uint8_t MBMS_flag; + OAI_NR_UECapability_t *UECap; + uint8_t *UECapability; + uint8_t UECapability_size; + + NR_SystemInformation_t *si[NB_CNX_UE]; + NR_SIB1_t *sib1[NB_CNX_UE]; + NR_SIB2_t *sib2[NB_CNX_UE]; + NR_SIB3_t *sib3[NB_CNX_UE]; + NR_SIB4_t *sib4[NB_CNX_UE]; + NR_SIB5_t *sib5[NB_CNX_UE]; + NR_SIB6_t *sib6[NB_CNX_UE]; + NR_SIB7_t *sib7[NB_CNX_UE]; + NR_SIB8_t *sib8[NB_CNX_UE]; + NR_SIB9_t *sib9[NB_CNX_UE]; + NR_SIB10_r16_t *sib10[NB_CNX_UE]; + NR_SIB11_r16_t *sib11[NB_CNX_UE]; + NR_SIB12_r16_t *sib12[NB_CNX_UE]; + NR_SIB13_r16_t *sib13[NB_CNX_UE]; + NR_SIB14_r16_t *sib14[NB_CNX_UE]; + plmn_t plmnID; + + NR_UE_RRC_INFO Info[NB_SIG_CNX_UE]; + NR_MIB_t *mib; - + + /* KeNB as computed from parameters within USIM card */ + uint8_t kgnb[32]; + /* Used integrity/ciphering algorithms */ + //RRC_LIST_TYPE(NR_SecurityAlgorithmConfig_t, NR_SecurityAlgorithmConfig) SecurityAlgorithmConfig_list; + NR_CipheringAlgorithm_t cipheringAlgorithm; + e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; + // lists // CellGroupConfig.rlc-BearerToAddModList RRC_LIST_TYPE(NR_RLC_BearerConfig_t, NR_maxLC_ID) RLC_Bearer_Config_list; @@ -118,7 +178,11 @@ typedef struct NR_UE_RRC_INST_s { RRC_LIST_TYPE(NR_CSI_ResourceConfig_t, NR_maxNrofCSI_ResourceConfigurations) CSI_ResourceConfig_list; // CellGroupConfig.spCellConfig.spCellConfigDedicated RRC_LIST_TYPE(NR_CSI_ReportConfig_t, NR_maxNrofCSI_ReportConfigurations) CSI_ReportConfig_list; - + + long selected_plmn_identity; + Rrc_State_NR_t nrRrcState; + Rrc_Sub_State_NR_t nrRrcSubState; + as_nas_info_t initialNasMsg; } NR_UE_RRC_INST_t; #endif diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 7bc7e4b90c..4019248441 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -59,12 +59,12 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*); \param size length of buffer*/ //TODO check to use which one //int8_t nr_rrc_ue_decode_rrcReconfiguration(const uint8_t *buffer, const uint32_t size); -int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const uint8_t *buffer, const uint32_t size); +int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, const uint8_t *buffer, const uint32_t size); /**\brief Process NR RRC connection reconfiguration via SRB3 \param rrcReconfiguration decoded rrc connection reconfiguration*/ -int8_t nr_rrc_ue_process_rrcReconfiguration(NR_RRCReconfiguration_t *rrcReconfiguration); +int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration); /**\prief Process measurement config from NR RRC connection reconfiguration message \param meas_config measurement configuration*/ @@ -73,7 +73,7 @@ int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config); /**\prief Process secondary cell group config from NR RRC connection reconfiguration message or EN-DC primitives \param cell_group_config secondary cell group configuration*/ //TODO check EN-DC function call flow. -int8_t nr_rrc_ue_process_scg_config(NR_CellGroupConfig_t *cell_group_config); +int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config); /**\prief Process radio bearer config from NR RRC connection reconfiguration message \param radio_bearer_config radio bearer configuration*/ @@ -86,6 +86,13 @@ int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_beare \param sdu_len length of buffer*/ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len); +/**\brief decode NR SIB1 message + \param module_idP module id + \param gNB_index gNB index + \param sduP pointer to buffer of ASN message + \param sdu_len length of buffer*/ +int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len); + /**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3 \param module_id module id \param gNB_index gNB index @@ -114,6 +121,16 @@ int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, const rb_id_t Srb_id, uint8_t *const buffer_pP); + +/**\brief RRC UE task. + \param void *args_p Pointer on arguments to start the task. */ +void *rrc_nrue_task(void *args_p); + +/**\brief RRC UE generate RRCSetupRequest message. + \param ctxt_pP protocol context + \param gNB_index gNB index */ +void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ); + /** @}*/ #endif diff --git a/common/utils/itti_analyzer/libparser/file_type.h b/openair2/SDAP/nr_sdap/sdap_gNB.c similarity index 79% rename from common/utils/itti_analyzer/libparser/file_type.h rename to openair2/SDAP/nr_sdap/sdap_gNB.c index 34ebea6745..ad84e4c273 100644 --- a/common/utils/itti_analyzer/libparser/file_type.h +++ b/openair2/SDAP/nr_sdap/sdap_gNB.c @@ -19,13 +19,12 @@ * contact@openairinterface.org */ -#include "types.h" +/*! \file sdap_gNB.c + * \brief sdap tasks for gNB + * \author Konstantinos Alexandris , Cedric Roux , Navid Nikaein + * \date 2018 + * \version 1.0 + */ +#define SDAP_GNB +#define SDAP_GNB_C -#ifndef FILE_TYPE_H_ -#define FILE_TYPE_H_ - -int file_type_file_print(types_t *type, int indent, FILE *file); - -int file_type_hr_display(types_t *type, int indent); - -#endif /* FILE_TYPE_H_ */ diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c new file mode 100644 index 0000000000..e11a92d691 --- /dev/null +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -0,0 +1,650 @@ +/* + * 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 itti_sim.c + * \brief simulator for itti message from node to UE + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + +#include + + +#include "T.h" + +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +#include + +#include "msc.h" + +#include "common/ran_context.h" + +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "PHY/phy_vars.h" +#include "SCHED/sched_common_vars.h" +#include "LAYER2/MAC/mac_vars.h" +#include "RRC/LTE/rrc_vars.h" +#include "gnb_config.h" +#include "SIMULATION/TOOLS/sim.h" + +#ifdef SMBV +#include "PHY/TOOLS/smbv.h" +unsigned short config_frames[4] = {2,9,11,13}; +#endif + +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" + +#ifndef OPENAIR2 + #include "UTIL/OTG/otg_vars.h" +#endif + +#include "intertask_interface.h" + + +#include "system.h" +#include +#include "PHY/TOOLS/phy_scope_interface.h" +#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" +#include "ngap_gNB.h" +#include "RRC/NR_UE/rrc_proto.h" +#include "RRC/NR_UE/rrc_vars.h" +#include "openair3/NAS/UE/nas_ue_task.h" + +pthread_cond_t nfapi_sync_cond; +pthread_mutex_t nfapi_sync_mutex; +int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex + +uint8_t nfapi_mode = 0; // Default to monolithic mode +uint32_t target_dl_mcs = 28; +uint32_t target_ul_mcs = 20; +uint32_t timing_advance = 0; +uint64_t num_missed_slots=0; + +int split73=0; +void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { + AssertFatal(false, "Must not be called in this context\n"); +} + +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. +int config_sync_var=-1; + +openair0_config_t openair0_cfg[MAX_CARDS]; + +//volatile int start_gNB = 0; +volatile int oai_exit = 0; + +//static int wait_for_sync = 0; + +unsigned int mmapped_dma=0; +int single_thread_flag=1; + +int8_t threequarter_fs=0; + +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + +//Temp fix for inexistent NR upper layer +unsigned char NB_gNB_INST = 1; + +static char *itti_dump_file = NULL; + +int UE_scan = 1; +int UE_scan_carrier = 0; +runmode_t mode = normal_txrx; +static double snr_dB=20; + +FILE *input_fd=NULL; + +int chain_offset=0; + + +uint8_t dci_Format = 0; +uint8_t agregation_Level =0xFF; + +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; + +char ref[128] = "internal"; +char channels[128] = "0"; + +int otg_enabled; + +extern void *udp_eNB_task(void *args_p); + +int transmission_mode=1; +int emulate_rf = 0; +int numerology = 0; +int usrp_tx_thread = 0; + + +double cpuf; + +extern char uecap_xer[1024]; +char uecap_xer_in=0; + +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; + +/* forward declarations */ +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 -----------------------------*/ + +struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; +struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; + +struct timespec clock_difftime(struct timespec start, struct timespec end) { + struct timespec temp; + + if ((end.tv_nsec-start.tv_nsec)<0) { + temp.tv_sec = end.tv_sec-start.tv_sec-1; + temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec-start.tv_sec; + temp.tv_nsec = end.tv_nsec-start.tv_nsec; + } + + return temp; +} + + + +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" +#define KGRN "\x1B[32m" +#define KBLU "\x1B[34m" +#define RESET "\033[0m" + + +void exit_function(const char *file, const char *function, const int line, const char *s) { + int ru_id; + + if (s != NULL) { + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); + } + + oai_exit = 1; + + if (RC.ru == NULL) + exit(-1); // likely init not completed, prevent crash or hang, exit now... + + for (ru_id=0; ru_idrfdevice.trx_end_func) { + RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); + RC.ru[ru_id]->rfdevice.trx_end_func = NULL; + } + + if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { + RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); + RC.ru[ru_id]->ifdevice.trx_end_func = NULL; + } + } + + sleep(1); //allow lte-softmodem threads to exit first + exit(1); +} + +void wait_gNBs(void) { + int i; + int waiting=1; + + while (waiting==1) { + printf("Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst %d)\n",RC.nb_nr_L1_inst); + usleep(50*1000); + waiting=0; + + for (i=0; iconfigured==0) { + waiting=1; + break; + } + } + } + + printf("gNB L1 are configured\n"); +} + +void wait_RUs(void) { + LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); + // wait for all RUs to be configured over fronthaul + pthread_mutex_lock(&RC.ru_mutex); + + while (RC.ru_mask>0) { + pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); + printf("RC.ru_mask:%02lx\n", RC.ru_mask); + } + + pthread_mutex_unlock(&RC.ru_mutex); + LOG_I(PHY,"RUs configured\n"); +} + + +int stop_L1L2(module_id_t gnb_id) { + return 0; +} + +int restart_L1L2(module_id_t gnb_id) { + return 0; +} + +int create_gNB_tasks(uint32_t gnb_nb) { + LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); + itti_wait_ready(1); + + + if (gnb_nb > 0) { + if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ + LOG_E(SCTP, "Create task for SCTP failed\n"); + return -1; + } + if (is_x2ap_enabled()) { + if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){ + LOG_E(X2AP, "Create task for X2AP failed\n"); + } + } + else { + LOG_I(X2AP, "X2AP is disabled.\n"); + } + } + + if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) { + if (gnb_nb > 0) { + if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) { + LOG_E(S1AP, "Create task for NGAP failed\n"); + return -1; + } + + + if(!emulate_rf){ + if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { + LOG_E(UDP_, "Create task for UDP failed\n"); + return -1; + } + } + + if (itti_create_task (TASK_GTPV1_U, &nr_gtpv1u_gNB_task, NULL) < 0) { + LOG_E(GTPU, "Create task for GTPV1U failed\n"); + return -1; + } + } + } + + + if (gnb_nb > 0) { + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } + LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); + + if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); + return -1; + } + } + + return 0; +} + + +static void get_options(void) { + + + paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; + + CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); + get_common_options(SOFTMODEM_GNB_BIT ); + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); + + + + + if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { + memset((void *)&RC,0,sizeof(RC)); + /* Read RC configuration file */ + NRRCConfig(); + NB_gNB_INST = RC.nb_nr_inst; + NB_RU = RC.nb_RU; + printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhu\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU); + } + +} + + +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_idssb_config.scs_common.value = 1; + config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD + 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; + } +} + +/* + * helper function to terminate a certain ITTI task + */ +void terminate_task(task_id_t task_id, module_id_t mod_id) { + LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + MessageDef *msg; + msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE); + itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} + +//extern void free_transport(PHY_VARS_gNB *); +extern void nr_phy_free_RU(RU_t *); + +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); + + 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); +} + + +int create_tasks_nrue(uint32_t ue_nb) { + LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); + itti_wait_ready(1); + + if (ue_nb > 0) { + printf("create TASK_RRC_NRUE\n"); + if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for RRC UE failed\n"); + return -1; + } + } + + + itti_wait_ready(0); + return 0; +} + + +void *itti_sim_ue_rrc_task( void *args_p) { + MessageDef *msg_p, *message_p; + instance_t instance; + unsigned int ue_mod_id; + int result; + itti_mark_task_ready (TASK_RRC_UE_SIM); + + while(1) { + // Wait for a message + itti_receive_msg (TASK_RRC_UE_SIM, &msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); + ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting RRC thread\n"); + itti_exit_task (); + break; + + case MESSAGE_TEST: + LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); + break; + case GNB_RRC_BCCH_DATA_IND: + message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_BCCH_DATA_IND); + memset (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); + NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = GNB_RRC_BCCH_DATA_IND(msg_p).size; + memcpy (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).size); + itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); + break; + case GNB_RRC_CCCH_DATA_IND: + message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND); + printf("receive GNB_RRC_CCCH_DATA_IND\n"); + memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).size); + NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = GNB_RRC_CCCH_DATA_IND(msg_p).size; + itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); + break; + case GNB_RRC_DCCH_DATA_IND: + printf("receive GNB_RRC_DCCH_DATA_IND\n"); + message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_DCCH_DATA_IND); + NR_RRC_DCCH_DATA_IND (message_p).dcch_index = GNB_RRC_DCCH_DATA_IND(msg_p).rbid; + NR_RRC_DCCH_DATA_IND (message_p).sdu_size = GNB_RRC_DCCH_DATA_IND(msg_p).size; + NR_RRC_DCCH_DATA_IND (message_p).sdu_p = GNB_RRC_DCCH_DATA_IND(msg_p).sdu; + itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); + break; + default: + LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + msg_p = NULL; + } +} + + +void *itti_sim_gnb_rrc_task( void *args_p) { + MessageDef *msg_p, *message_p; + instance_t instance; + unsigned int ue_mod_id; + int result; + itti_mark_task_ready (TASK_RRC_GNB_SIM); + + while(1) { + // Wait for a message + itti_receive_msg (TASK_RRC_GNB_SIM, &msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); + ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting RRC thread\n"); + itti_exit_task (); + break; + + case MESSAGE_TEST: + LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); + break; + case UE_RRC_CCCH_DATA_IND: + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND); + NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = UE_RRC_CCCH_DATA_IND(msg_p).size; + memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).size); + itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p); + break; + case UE_RRC_DCCH_DATA_IND: + message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_DCCH_DATA_IND); + NR_RRC_DCCH_DATA_IND (message_p).sdu_size = UE_RRC_DCCH_DATA_IND(msg_p).size; + NR_RRC_DCCH_DATA_IND (message_p).dcch_index = UE_RRC_DCCH_DATA_IND(msg_p).rbid; + NR_RRC_DCCH_DATA_IND (message_p).sdu_p = UE_RRC_DCCH_DATA_IND(msg_p).sdu; + itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p); + break; + + default: + LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + msg_p = NULL; + } +} + + +int main( int argc, char **argv ) +{ + start_background_system(); + + ///static configuration for NR at the moment + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + set_softmodem_sighandler(); +#ifdef DEBUG_CONSOLE + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); +#endif + + logInit(); + //configure_linux(); + printf("Reading in command-line options\n"); + get_options (); + + if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { + fprintf(stderr,"Getting configuration failed\n"); + exit(-1); + } + + AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1; +// AMF_MODE_ENABLED = 0; + NGAP_CONF_MODE = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; + +#if T_TRACER + T_Config_Init(); +#endif + //randominit (0); + set_taus_seed (0); + printf("configuring for RAU/RRU\n"); + + if (opp_enabled ==1) { + reset_opp_meas(); + } + + cpuf=get_cpu_freq_GHz(); + itti_init(TASK_MAX, tasks_info); + // initialize mscgen log after ITTI + MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); + + + init_opt(); + + 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 + AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n"); + } else { + printf("No ITTI, Initializing L1\n"); + return 0; + } + + if(itti_create_task (TASK_RRC_GNB_SIM, itti_sim_gnb_rrc_task, NULL) < 0){ + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + + openair_rrc_top_init_ue_nr("./"); + + if (create_tasks_nrue(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + + if(itti_create_task (TASK_RRC_UE_SIM, itti_sim_ue_rrc_task, NULL) < 0){ + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + + printf("Sending sync to all threads\n"); + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); + // wait for end of program + printf("TYPE TO TERMINATE\n"); + + usleep(100000); + protocol_ctxt_t ctxt; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + + + ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[0]); + + if(ue_context_p == NULL){ + printf("ue_context_p == NULL"); + } + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + 0, + ENB_FLAG_YES, + 0, + 0, + 0); + NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED; + + rrc_ue_generate_RRCSetupRequest(&ctxt, 0); + + printf("Entering ITTI signals handler\n"); + itti_wait_tasks_end(); + printf("Returned from ITTI signal handler\n"); + oai_exit=1; + printf("oai_exit=%d\n",oai_exit); + + printf("stopping MODEM threads\n"); + + + /* release memory used by the RU/gNB threads (incomplete), after all + * threads have been stopped (they partially use the same memory) */ + + pthread_cond_destroy(&sync_cond); + pthread_mutex_destroy(&sync_mutex); + + logClean(); + printf("Bye.\n"); + return 0; +} + + + diff --git a/openair2/UTIL/OPT/mac_pcap.h b/openair2/UTIL/OPT/mac_pcap.h index 3141d17d59..c443ceb1fb 100644 --- a/openair2/UTIL/OPT/mac_pcap.h +++ b/openair2/UTIL/OPT/mac_pcap.h @@ -6,6 +6,7 @@ #include #define MAC_LTE_DLT 147 +#define DLT_IPV4 228 /********************************************************/ /* Definitions and descriptions come from: http://wiki.wireshark.org/Development/LibpcapFileFormat */ @@ -29,20 +30,4 @@ typedef struct pcaprec_hdr_s { unsigned int orig_len; /* actual length of packet */ } pcaprec_hdr_t; -/* Context information for every MAC PDU that will be logged */ -typedef struct MAC_Context_Info_t { - unsigned short radioType; - unsigned char direction; - unsigned char rntiType; - unsigned short rnti; - unsigned short ueid; - unsigned char isRetx; - unsigned char crcStatusOK; - - unsigned short sysFrameNumber; - unsigned short subFrameNumber; - - unsigned int subframesSinceCaptureStart; -} MAC_Context_Info_t; - #endif diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index 6861e09cb1..ab591d3a65 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -73,7 +73,7 @@ typedef guint8 gboolean; /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------*/ #define OPT_PARAMS_DESC { \ - {"type" , CONFIG_HLP_TYPEMON, 0, strptr:&in_type, defstrval:"none", TYPE_STRING, 0}, \ + {"type" , CONFIG_HLP_TYPEMON, 0, strptr:(char**)&in_type, defstrval:"none", TYPE_STRING, 0}, \ {"ip" , CONFIG_HLP_L2MONIP, 0, strptr:(char**)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {"path" , CONFIG_HLP_L2MONPATH, 0, strptr:(char**)&in_path,defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, 0}, \ } diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 8c6a74e042..3f416c9255 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -90,6 +90,7 @@ what about the implementation #include #include +#include #include "common/config/config_userapi.h" #include "opt.h" #include "common/utils/system.h" @@ -99,8 +100,6 @@ int opt_enabled=0; //static unsigned char g_PDUBuffer[1600]; //static unsigned int g_PDUOffset; -static char in_ip[128]={0}; -static char in_path[128]={0}; FILE *file_fd = NULL; pcap_hdr_t file_header = { 0xa1b2c3d4, /* magic number */ @@ -108,10 +107,14 @@ pcap_hdr_t file_header = { 0, /* timezone */ 0, /* sigfigs - apparently all tools do this */ 65535, /* snaplen - this should be long enough */ - MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */ + DLT_IPV4 + //MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */ }; trace_mode_t opt_type = OPT_NONE; +static char *in_type=NULL; +static char *in_path=NULL; +static char *in_ip=NULL; static unsigned int subframesSinceCaptureStart; static int g_socksd = -1;/* UDP socket used for sending frames */ @@ -131,8 +134,80 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, guint8 oob_event, guint8 oob_event_value, uint8_t *pdu_buffer, unsigned int pdu_buffer_size); -static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, - const unsigned char *PDU, unsigned int length); +unsigned short checksum(unsigned short *ptr, int length) { + int sum = 0; + u_short answer = 0; + unsigned short *w = ptr; + int nleft = length; + + while(nleft > 1) { + sum += *w++; + nleft -= 2; + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + answer = ~sum; + return(answer); +} + +/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */ +static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU, + unsigned int length) { + pcaprec_hdr_t packet_header; + // IPv4 header + typedef struct ip_hdr { + unsigned char ip_verlen; // 4-bit IPv4 version 4-bit header length (in 32-bit words) + unsigned char ip_tos; // IP type of service + unsigned short ip_totallength; // Total length + unsigned short ip_id; // Unique identifier + unsigned short ip_offset; // Fragment offset field + unsigned char ip_ttl; // Time to live + unsigned char ip_protocol; // Protocol(TCP,UDP etc) + unsigned short ip_checksum; // IP checksum + unsigned int ip_srcaddr; // Source address + unsigned int ip_destaddr; // Source address + } IPV4_HDR; + // Define the UDP header + typedef struct udp_hdr { + unsigned short src_portno; // Source port no. + unsigned short dst_portno; // Dest. port no. + unsigned short udp_length; // Udp packet length + unsigned short udp_checksum; // Udp checksum (optional) + } UDP_HDR; + IPV4_HDR IPheader= {0}; + IPheader.ip_verlen = (4 << 4) | (sizeof(IPV4_HDR) / sizeof(uint32_t)); + IPheader.ip_totallength = htons(sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length); + IPheader.ip_ttl = 8; // Time-to-live is eight + IPheader.ip_protocol = IPPROTO_UDP; + IPheader.ip_srcaddr = inet_addr(in_ip); + IPheader.ip_destaddr = inet_addr(in_ip); + IPheader.ip_checksum = checksum((unsigned short *)&IPheader, sizeof(IPV4_HDR)); + // Initialize the UDP header + UDP_HDR UDPheader; + UDPheader.src_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT); + UDPheader.dst_portno = htons( PACKET_MAC_LTE_DEFAULT_UDP_PORT); + UDPheader.udp_length = htons(sizeof(UDP_HDR) + length); + UDPheader.udp_checksum = 0; + /****************************************************************/ + /* PCAP Header */ + /* TODO: Timestamp might want to be relative to a more sensible + base time... */ + struct timeval tv; + gettimeofday(&tv, NULL); + packet_header.ts_sec = tv.tv_sec; + packet_header.ts_usec = tv.tv_usec; + packet_header.incl_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length; + packet_header.orig_len =sizeof(IPV4_HDR) + sizeof(UDP_HDR) + length; + /***************************************************************/ + /* Now write everything to the file */ + fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd); + fwrite(&IPheader, sizeof(IPV4_HDR), 1, file_fd); + fwrite(&UDPheader, sizeof(UDP_HDR), 1, file_fd); + fwrite(PDU, 1, length, file_fd); + fflush(file_fd); + return length; +} static void *opt_listener_thread(void *arg) { ssize_t ret; @@ -198,7 +273,6 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) { } threadCreate(&opt_listener.thread, opt_listener_thread, NULL, "flexran", -1, OAI_PRIORITY_RT_LOW); - return 0; } @@ -321,67 +395,20 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, frameOffset += pdu_buffer_size; } - /* Send out the data over the UDP socket */ - bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, - (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); + if ( opt_type == OPT_WIRESHARK ) + /* Send out the data over the UDP socket */ + bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, + (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); + else + bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset); if (bytesSent != frameOffset) { - LOG_W(OPT, "sendto() failed (not a thread-safe func)- expected %d bytes, got %ld (errno=%d)\n", + LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n", frameOffset, bytesSent, errno); //exit(1); } } -/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */ -static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context, - const uint8_t *PDU, - unsigned int length) -{ - pcaprec_hdr_t packet_header; - uint8_t context_header[256]; - int offset = 0; - unsigned short tmp16; - /*****************************************************************/ - /* Context information (same as written by UDP heuristic clients */ - context_header[offset++] = context->radioType; - context_header[offset++] = context->direction; - context_header[offset++] = context->rntiType; - /* RNTI */ - context_header[offset++] = MAC_LTE_RNTI_TAG; - tmp16 = htons(context->rnti); - memcpy(context_header+offset, &tmp16, 2); - offset += 2; - /* UEId */ - context_header[offset++] = MAC_LTE_UEID_TAG; - tmp16 = htons(context->ueid); - memcpy(context_header+offset, &tmp16, 2); - offset += 2; - /* Subframe number */ - context_header[offset++] = MAC_LTE_FRAME_SUBFRAME_TAG; - tmp16 = htons(context->subFrameNumber); - memcpy(context_header+offset, &tmp16, 2); - offset += 2; - /* CRC Status */ - context_header[offset++] = MAC_LTE_CRC_STATUS_TAG; - context_header[offset++] = context->crcStatusOK; - /* Data tag immediately preceding PDU */ - context_header[offset++] = MAC_LTE_PAYLOAD_TAG; - /****************************************************************/ - /* PCAP Header */ - /* TODO: Timestamp might want to be relative to a more sensible - base time... */ - packet_header.ts_sec = context->subframesSinceCaptureStart / 1000; - packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000; - packet_header.incl_len = offset + length; - packet_header.orig_len = offset + length; - /***************************************************************/ - /* Now write everything to the file */ - fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd); - fwrite(context_header, 1, offset, file_fd); - fwrite(PDU, 1, length, file_fd); - return 1; -} - #include extern RAN_CONTEXT_t RC; #include @@ -389,7 +416,6 @@ extern RAN_CONTEXT_t RC; void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, int oob_event_value) { - MAC_Context_Info_t pdu_context; int radioType=FDD_RADIO; LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n", direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber); @@ -405,53 +431,41 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p switch (opt_type) { case OPT_WIRESHARK : - if (g_socksd == -1) { + if (g_socksd == -1) return; - } - SendFrame( radioType, - (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, - rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber, - 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus - oob_event,oob_event_value, - pdu_buffer, pdu_buffer_size); break; case OPT_PCAP: - if (file_fd == NULL) { + if (file_fd == NULL) return; - } - pdu_context.radioType = radioType; - pdu_context.direction = (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK - : DIRECTION_UPLINK; - pdu_context.rntiType = rntiType; - pdu_context.rnti = rnti; - pdu_context.ueid = ueid; - pdu_context.isRetx = 0; - pdu_context.crcStatusOK =1; - pdu_context.sysFrameNumber = sysFrameNumber; - pdu_context.subFrameNumber = subFrameNumber; - pdu_context.subframesSinceCaptureStart = subframesSinceCaptureStart++; - MAC_LTE_PCAP_WritePDU( &pdu_context, pdu_buffer, pdu_buffer_size); break; case OPT_TSHARK: default: + return; break; } + + SendFrame( radioType, + (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, + rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber, + 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus + oob_event,oob_event_value, + pdu_buffer, pdu_buffer_size); } + /*---------------------------------------------------*/ -int init_opt(void) -{ - char *in_type=NULL; +int init_opt(void) { + in_type=malloc(200); + in_ip=malloc(200); + in_path=malloc(200); paramdef_t opt_params[] = OPT_PARAMS_DESC ; checkedparam_t opt_checkParams[] = OPTPARAMS_CHECK_DESC; - uint16_t in_port=0; config_set_checkfunctions(opt_params, opt_checkParams, sizeof(opt_params)/sizeof(paramdef_t)); config_get( opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX); - subframesSinceCaptureStart = 0; int tmptype = config_get_processedint( &(opt_params[OPTTYPE_IDX])); @@ -462,25 +476,21 @@ int init_opt(void) } else if (tmptype == OPT_PCAP && strlen(in_path) > 0) { opt_type = OPT_PCAP; opt_enabled=1; - LOG_I(OPT,"Enabling OPT for PCAP with the following file %s \n",in_path); } else if (tmptype == OPT_WIRESHARK && strlen(in_ip) > 0) { opt_enabled=1; opt_type = OPT_WIRESHARK; - LOG_I(OPT,"Enabling OPT for wireshark for local interface %s\n",in_ip); } else { LOG_E(OPT,"Invalid OPT configuration\n"); config_printhelp(opt_params,sizeof(opt_params)/sizeof(paramdef_t),OPT_CONFIGPREFIX); } - in_port = PACKET_MAC_LTE_DEFAULT_UDP_PORT; - // trace_mode switch (opt_type) { case OPT_WIRESHARK: - + LOG_I(OPT,"mode Wireshark: ip %s port %d\n", in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT); /* Create local server socket only if using localhost address */ - if (strcmp(in_ip, "127.0.0.1") == 0) { - opt_create_listener_socket(in_ip, in_port); + if (strncmp(in_ip, "127.0.0.1", 4) == 0) { + opt_create_listener_socket(in_ip, PACKET_MAC_LTE_DEFAULT_UDP_PORT); } g_socksd = socket(AF_INET, SOCK_DGRAM, 0); @@ -493,11 +503,12 @@ int init_opt(void) /* Get remote IP address from the function argument */ g_serv_addr.sin_family = AF_INET; - g_serv_addr.sin_port = htons(in_port); + g_serv_addr.sin_port = htons(PACKET_MAC_LTE_DEFAULT_UDP_PORT); g_serv_addr.sin_addr.s_addr = inet_addr(in_ip); break; case OPT_PCAP: + LOG_I(OPT,"mode PCAB : path is %s \n",in_path); file_fd = fopen(in_path, "w"); if (file_fd == NULL) { @@ -516,19 +527,9 @@ int init_opt(void) default: opt_type = OPT_NONE; - LOG_W(OPT, "supported Option\n"); + LOG_E(OPT,"Unsupported or unknown mode %d \n", opt_type); break; } - - if ( opt_type == OPT_WIRESHARK ) - LOG_E(OPT,"mode Wireshark: ip %s port %d\n", in_ip, in_port); - else if (opt_type == OPT_PCAP) - LOG_E(OPT,"mode PCAB : path is %s \n",in_path); - else - LOG_E(OPT,"Unsupported or unknown mode %d \n", opt_type); - - // mac_info = (mac_info*)malloc16(sizeof(mac_lte_info)); - // memset(mac_info, 0, sizeof(mac_lte_info)+pdu_buffer_size + 8); return (1); } diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index 3df350541f..304dd07042 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -55,6 +55,8 @@ typedef enum { int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, const uint8_t key[32], uint8_t **out); +int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out); //#define derive_key_nas_enc(aLGiD, kEY, kNAS) derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS) @@ -72,6 +74,19 @@ int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, #define derive_key_up_int(aLGiD, kEY, kNAS) \ derive_key(UP_INT_ALG, aLGiD, kEY, kNAS) +// 5G SA +#define nr_derive_key_rrc_enc(aLGiD, kEY, kRRC) \ + nr_derive_key(RRC_ENC_ALG, aLGiD, kEY, kRRC) + +#define nr_derive_key_rrc_int(aLGiD, kEY, kRRC) \ + nr_derive_key(RRC_INT_ALG, aLGiD, kEY, kRRC) + +#define nr_derive_key_up_enc(aLGiD, kEY, kUP) \ + nr_derive_key(UP_ENC_ALG, aLGiD, kEY, kUP) + +#define nr_derive_key_up_int(aLGiD, kEY, kUP) \ + nr_derive_key(UP_INT_ALG, aLGiD, kEY, kUP) + typedef struct { uint8_t *key; uint32_t key_length; diff --git a/openair2/UTIL/OSA/osa_internal.h b/openair2/UTIL/OSA/osa_internal.h index 1f5aab5df8..f4a70c7e95 100644 --- a/openair2/UTIL/OSA/osa_internal.h +++ b/openair2/UTIL/OSA/osa_internal.h @@ -36,6 +36,8 @@ #define FC_ALG_KEY_DER (0x15) #define FC_KASME_TO_CK (0x16) +#define NR_FC_ALG_KEY_DER (0x69) + #ifndef hton_int32 # define hton_int32(x) \ (((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | \ diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index 237592bd17..71c7793fa0 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -97,6 +97,34 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, return 0; } + +int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, + const uint8_t key[32], uint8_t **out) +{ + uint8_t string[7]; + + /* FC */ + string[0] = NR_FC_ALG_KEY_DER; + + /* P0 = algorithm type distinguisher */ + string[1] = (uint8_t)(alg_type & 0xFF); + + /* L0 = length(P0) = 1 */ + string[2] = 0x00; + string[3] = 0x01; + + /* P1 */ + string[4] = alg_id; + + /* L1 = length(P1) = 1 */ + string[5] = 0x00; + string[6] = 0x01; + + kdf(string, 7, key, 32, out, 32); + + return 0; +} + /* int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) { diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 4789efeebe..58535646fd 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -133,7 +133,7 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa dump_trees(); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + X2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -159,7 +159,7 @@ static void x2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_enb_data_p; - printf("x2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance); + printf("x2ap_eNB_handle_sctp_association_ind at 1 (called for instance %ld)\n", instance); dump_trees(); DevAssert(sctp_new_association_ind != NULL); instance_p = x2ap_eNB_get_instance(instance); @@ -207,7 +207,7 @@ int x2ap_eNB_init_sctp (x2ap_eNB_instance_t *instance_p, sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_X2AP, SCTP_INIT_MSG_MULTI_REQ); + message = itti_alloc_new_message (TASK_X2AP, 0, SCTP_INIT_MSG_MULTI_REQ); sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = enb_port_for_X2C; sctp_init->ppid = X2AP_SCTP_PPID; @@ -241,7 +241,7 @@ static void x2ap_eNB_register_eNB(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_enb_data = NULL; DevAssert(instance_p != NULL); DevAssert(target_eNB_ip_address != NULL); - message = itti_alloc_new_message(TASK_X2AP, SCTP_NEW_ASSOCIATION_REQ_MULTI); + message = itti_alloc_new_message(TASK_X2AP, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI); sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; sctp_new_association_req->port = enb_port_for_X2C; sctp_new_association_req->ppid = X2AP_SCTP_PPID; @@ -286,7 +286,7 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, DevCheck(new_instance->tac == x2ap_register_eNB->tac, new_instance->tac, x2ap_register_eNB->tac, 0); DevCheck(new_instance->mcc == x2ap_register_eNB->mcc, new_instance->mcc, x2ap_register_eNB->mcc, 0); DevCheck(new_instance->mnc == x2ap_register_eNB->mnc, new_instance->mnc, x2ap_register_eNB->mnc, 0); - X2AP_WARN("eNB[%d] already registered\n", instance); + X2AP_WARN("eNB[%ld] already registered\n", instance); } else { new_instance = calloc(1, sizeof(x2ap_eNB_instance_t)); DevAssert(new_instance != NULL); @@ -310,14 +310,21 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, x2ap_register_eNB->t_dc_overall); for (int i = 0; i< x2ap_register_eNB->num_cc; i++) { - new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; - new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i]; + if(new_instance->cell_type == CELL_MACRO_GNB){ + new_instance->nr_band[i] = x2ap_register_eNB->nr_band[i]; + new_instance->tdd_nRARFCN[i] = x2ap_register_eNB->nrARFCN[i]; + } + else{ + new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; + new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i]; + new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i]; + new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i]; + } + new_instance->uplink_frequency_offset[i] = x2ap_register_eNB->uplink_frequency_offset[i]; new_instance->Nid_cell[i] = x2ap_register_eNB->Nid_cell[i]; new_instance->N_RB_DL[i] = x2ap_register_eNB->N_RB_DL[i]; new_instance->frame_type[i] = x2ap_register_eNB->frame_type[i]; - new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i]; - new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i]; } DevCheck(x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS, @@ -332,7 +339,7 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, new_instance->enb_port_for_X2C = x2ap_register_eNB->enb_port_for_X2C; /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ x2ap_eNB_insert_new_instance(new_instance); - X2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n", + X2AP_INFO("Registered new eNB[%ld] and %s eNB id %u\n", instance, x2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", x2ap_register_eNB->eNB_id); @@ -343,7 +350,7 @@ void x2ap_eNB_handle_register_eNB(instance_t instance, return; } - X2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n", + X2AP_INFO("eNB[%ld] eNB id %u acting as a listner (server)\n", instance, x2ap_register_eNB->eNB_id); } } @@ -370,7 +377,7 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf( /* Trying to connect to the provided list of eNB ip address */ for (index = 0; index < instance->nb_x2; index++) { - X2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n", + X2AP_INFO("eNB[%ld] eNB id %u acting as an initiator (client)\n", instance_id, instance->eNB_id); x2ap_eNB_register_eNB(instance, &instance->target_enb_x2_ip_address[index], @@ -626,67 +633,67 @@ void *x2ap_task(void *arg) { break; case X2AP_SUBFRAME_PROCESS: - x2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + x2ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); break; case X2AP_REGISTER_ENB_REQ: - x2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_REGISTER_ENB_REQ(received_msg)); break; case X2AP_HANDOVER_REQ: - x2ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_handover_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_HANDOVER_REQ(received_msg)); break; case X2AP_HANDOVER_REQ_ACK: - x2ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_handover_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_HANDOVER_REQ_ACK(received_msg)); break; case X2AP_UE_CONTEXT_RELEASE: - x2ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_ue_context_release(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_UE_CONTEXT_RELEASE(received_msg)); break; case X2AP_ENDC_SGNB_ADDITION_REQ: - x2ap_eNB_handle_sgNB_add_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_sgNB_add_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_ENDC_SGNB_ADDITION_REQ(received_msg)); break; case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: - x2ap_gNB_trigger_sgNB_add_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_gNB_trigger_sgNB_add_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(received_msg)); LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n"); break; case X2AP_ENDC_SGNB_RECONF_COMPLETE: - x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg)); break; case X2AP_ENDC_SGNB_RELEASE_REQUEST: - x2ap_eNB_handle_sgNB_release_request(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_sgNB_release_request(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &X2AP_ENDC_SGNB_RELEASE_REQUEST(received_msg)); break; case SCTP_INIT_MSG_MULTI_CNF: - x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); break; case SCTP_NEW_ASSOCIATION_RESP: - x2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_NEW_ASSOCIATION_IND: - x2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind); break; case SCTP_DATA_IND: - x2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + x2ap_eNB_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index 3d8efd8cd4..063302d03a 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -179,6 +179,7 @@ typedef struct x2ap_eNB_instance_s { uint32_t specialSubframe[MAX_NUM_CCs]; //#ifdef Rel15 + int32_t nr_band[MAX_NUM_CCs]; uint32_t tdd_nRARFCN[MAX_NUM_CCs]; int16_t nr_SCS[MAX_NUM_CCs]; //#endif diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 1e549d8cbe..fdce8678b0 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -39,7 +39,6 @@ #include "x2ap_ids.h" #include "x2ap_eNB_itti_messaging.h" -#include "X2AP_SupportedSULFreqBandItem.h" #include "msc.h" #include "assertions.h" @@ -1236,7 +1235,6 @@ int x2ap_gNB_generate_ENDC_x2_setup_request( X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC; X2AP_PLMN_Identity_t *plmn; ServedNRcellsENDCX2ManagementList__Member *servedCellMember; - X2AP_SupportedSULFreqBandItem_t *SULFreqBandItem; uint8_t *buffer; uint32_t len; @@ -1284,8 +1282,8 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqIEs__value_PR_ServedNRcellsENDCX2ManagementList; { - for (int i = 0; inum_cc; i++){ - servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member)); + for (int i = 0; inum_cc; i++){ + servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member)); { servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i]; @@ -1299,60 +1297,63 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC); X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac, - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t)); { MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn); ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn); } - - if (instance_p->frame_type[i] == TDD) { + if (instance_p->frame_type[i] == TDD) { X2AP_FreqBandNrItem_t *freq_band; servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd; - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i]; + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = instance_p->tdd_nRARFCN[i]; /* addition of Frequency Band List */ freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t)); if (freq_band == NULL) exit(1); - freq_band->freqBandIndicatorNr = instance_p->eutra_band[0]; - - SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t)); - SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */ - ASN_SEQUENCE_ADD(&freq_band->supportedSULBandList.list, SULFreqBandItem); + freq_band->freqBandIndicatorNr = instance_p->nr_band[i]; ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band); switch (instance_p->N_RB_DL[i]) { - case 50: - //This is not correct. Just to be able to test X2 only using an eNB instead of gNB - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51; + case 32: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32; + break; + case 66: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb66; + break; + case 93 : + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93; + break; + case 106: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106; + break; + case 121: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121; + break; + case 217: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb217; + break; + case 273: + servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb273; + break; + /*More cases to be added */ + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); break; - case 93 : - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93; - break; - case 106: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106; - break; - case 121: - servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121; - break; - /*More cases to be added */ - default: - AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); - break; - } - } + } + } else { AssertFatal(0,"ENDC_X2Setuprequest not supported for FDD!"); } - /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */ - INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); + /*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */ + INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration); } ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember); - } } + } ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC); @@ -1438,7 +1439,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( } if (instance_p->frame_type[i] == FDD) { - servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD; servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i]; servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i]; switch (instance_p->N_RB_DL[i]) { @@ -1472,12 +1473,98 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( } } else { - AssertFatal(0,"X2Setupresponse not supported for TDD!"); + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i]; + + switch (instance_p->subframeAssignment[i]) { + case 0: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0; + break; + case 1: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1; + break; + case 2: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2; + break; + case 3: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3; + break; + case 4: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4; + break; + case 5: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5; + break; + case 6: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + switch (instance_p->specialSubframe[i]) { + case 0: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0; + break; + case 1: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1; + break; + case 2: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2; + break; + case 3: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3; + break; + case 4: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4; + break; + case 5: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5; + break; + case 6: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6; + break; + case 7: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7; + break; + case 8: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8; + break; + default: + AssertFatal(0,"Failed: Check value for subframeAssignment"); + break; + } + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal; + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal; + + switch (instance_p->N_RB_DL[i]) { + case 6: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6; + break; + case 15: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15; + break; + case 25: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25; + break; + case 50: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50; + break; + case 75: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75; + break; + case 100: + servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100; + break; + default: + AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL"); + break; + } } } - ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember); + ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember); } - } + } ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC); @@ -1588,7 +1675,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( for (int i=0;iid = X2AP_ProtocolIE_ID_id_E_RABs_ToBeAdded_SgNBAddReq_Item; - e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_ignore; + e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->criticality = X2AP_Criticality_reject; e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item; e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item; { diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index bbdeaf0ac8..f0e0fa9c23 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -230,7 +230,7 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data if (instance_p->x2_target_enb_associated_nb == 0) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_X2AP, X2AP_DEREGISTERED_ENB_IND); + message_p = itti_alloc_new_message(TASK_X2AP, 0, X2AP_DEREGISTERED_ENB_IND); X2AP_DEREGISTERED_ENB_IND(message_p).nb_x2 = 0; itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); } @@ -250,7 +250,7 @@ void x2ap_handle_x2_setup_message(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data if (instance_p->x2_target_enb_pending_nb == 0) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_X2AP, X2AP_REGISTER_ENB_CNF); + message_p = itti_alloc_new_message(TASK_X2AP, 0, X2AP_REGISTER_ENB_CNF); X2AP_REGISTER_ENB_CNF(message_p).nb_x2 = instance_p->x2_target_enb_associated_nb; itti_send_msg_to_task(TASK_ENB_APP, instance_p->instance, message_p); } @@ -480,7 +480,7 @@ x2ap_eNB_handle_x2_setup_request(instance_t instance, return -1; } - msg = itti_alloc_new_message(TASK_X2AP, X2AP_SETUP_REQ); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_SETUP_REQ); X2AP_SETUP_REQ(msg).num_cc = ie->value.choice.ServedCells.list.count; @@ -598,7 +598,7 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance, return -1; } - msg = itti_alloc_new_message(TASK_X2AP, X2AP_SETUP_RESP); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_SETUP_RESP); X2AP_SETUP_RESP(msg).num_cc = ie->value.choice.ServedCells.list.count; @@ -724,7 +724,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_HANDOVER_REQ); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); @@ -865,7 +865,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_REQ_ACK); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_HANDOVER_REQ_ACK); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); @@ -1005,7 +1005,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - msg = itti_alloc_new_message(TASK_X2AP, X2AP_UE_CONTEXT_RELEASE); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_UE_CONTEXT_RELEASE); X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_UEContextRelease_IEs_t, ie, x2UEContextRelease, X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true); @@ -1150,7 +1150,7 @@ int x2ap_eNB_handle_handover_cancel (instance_t instance, exit(1); } - msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_CANCEL); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_HANDOVER_CANCEL); X2AP_HANDOVER_CANCEL(msg).rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); X2AP_HANDOVER_CANCEL(msg).cause = cause; @@ -1199,7 +1199,7 @@ int x2ap_eNB_handle_senb_addition_request (instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - msg = itti_alloc_new_message(TASK_X2AP, X2AP_SENB_ADDITION_REQ); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_SENB_ADDITION_REQ); /*MeNB_UE_X2AP_ID */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SeNBAdditionRequest_IEs_t, ie, x2SeNBAdditionRequest, @@ -1410,7 +1410,7 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup, true); - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SETUP_REQ); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_SETUP_REQ); if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); @@ -1703,7 +1703,7 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, DevAssert(instance_p != NULL); //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_SGNB_ADDITION_REQ); /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, @@ -1851,7 +1851,7 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, DevAssert(instance_p != NULL); //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).gnb_x2_assoc_id = assoc_id; @@ -1997,7 +1997,7 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, DevAssert(instance_p != NULL); //Allocate an ITTI X2AP_sGNB_reconfiguration_complete message - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_SGNB_RECONF_COMPLETE); /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, @@ -2135,7 +2135,7 @@ int x2ap_gNB_handle_ENDC_sGNB_release_request(instance_t instance, } if (rnti != -1) { - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RELEASE_REQUEST); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_SGNB_RELEASE_REQUEST); X2AP_ENDC_SGNB_RELEASE_REQUEST(msg).rnti = rnti; @@ -2228,7 +2228,7 @@ int x2ap_gNB_handle_ENDC_sGNB_release_required(instance_t instance, gnb_rnti = id_target; - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RELEASE_REQUIRED); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_SGNB_RELEASE_REQUIRED); X2AP_ENDC_SGNB_RELEASE_REQUIRED(msg).gnb_rnti = gnb_rnti; itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); diff --git a/openair2/X2AP/x2ap_eNB_itti_messaging.c b/openair2/X2AP/x2ap_eNB_itti_messaging.c index 7573d9be89..26e26ba411 100644 --- a/openair2/X2AP/x2ap_eNB_itti_messaging.c +++ b/openair2/X2AP/x2ap_eNB_itti_messaging.c @@ -36,7 +36,7 @@ void x2ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_X2AP, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_X2AP, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -54,7 +54,7 @@ void x2ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t asso MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_X2AP, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_X2AP, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; diff --git a/openair2/X2AP/x2ap_eNB_management_procedures.c b/openair2/X2AP/x2ap_eNB_management_procedures.c index 469a76a261..a0cc0d1124 100644 --- a/openair2/X2AP/x2ap_eNB_management_procedures.c +++ b/openair2/X2AP/x2ap_eNB_management_procedures.c @@ -116,7 +116,7 @@ void dump_trees(void) x2ap_eNB_instance_t *zz; STAILQ_FOREACH(zz, &x2ap_eNB_internal_data.x2ap_eNB_instances_head, x2ap_eNB_entries) { -printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +printf("here comes the tree (instance %ld):\n---------------------------------------------\n", zz->instance); dump_tree(zz->x2ap_enb_head.rbh_root); printf("---------------------------------------------\n"); } diff --git a/openair2/X2AP/x2ap_timers.c b/openair2/X2AP/x2ap_timers.c index 29e887504f..98674de51b 100644 --- a/openair2/X2AP/x2ap_timers.c +++ b/openair2/X2AP/x2ap_timers.c @@ -101,7 +101,7 @@ void x2ap_check_timers(instance_t instance) X2AP_CAUSE_T_DC_PREP_TIMEOUT); /* inform RRC of timeout */ - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_DC_PREP_TIMEOUT); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_DC_PREP_TIMEOUT); X2AP_ENDC_DC_PREP_TIMEOUT(msg).rnti = x2ap_id_get_rnti(m, i); itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); @@ -125,7 +125,7 @@ void x2ap_check_timers(instance_t instance) id_source, id_target, X2AP_CAUSE_T_DC_OVERALL_TIMEOUT); /* inform RRC of timeout */ - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_DC_OVERALL_TIMEOUT); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_ENDC_DC_OVERALL_TIMEOUT); X2AP_ENDC_DC_OVERALL_TIMEOUT(msg).rnti = x2ap_id_get_rnti(m, i); itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); @@ -144,7 +144,7 @@ lte_handover_timeout: x2ap_eNB_generate_x2_handover_cancel(instance_p, target, i, cause); /* inform RRC of cancellation */ - msg = itti_alloc_new_message(TASK_X2AP, X2AP_HANDOVER_CANCEL); + msg = itti_alloc_new_message(TASK_X2AP, 0, X2AP_HANDOVER_CANCEL); X2AP_HANDOVER_CANCEL(msg).rnti = x2ap_id_get_rnti(m, i); X2AP_HANDOVER_CANCEL(msg).cause = cause; itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); diff --git a/openair3/COMMON/messages_types.h b/openair3/COMMON/messages_types.h index f91881bf11..f8fd464288 100644 --- a/openair3/COMMON/messages_types.h +++ b/openair3/COMMON/messages_types.h @@ -39,6 +39,7 @@ #include "udp_messages_types.h" #include "mme_app_messages_types.h" #include "m2ap_messages_types.h" +#include "ngap_messages_types.h" #endif /* MESSAGES_TYPES_H_ */ diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 1e2954ba95..4769380d18 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -135,7 +135,7 @@ static int gtpv1u_eNB_send_init_udp(const Gtpv1uS1Req *req) { // Create and alloc new message MessageDef *message_p; struct in_addr addr= {0}; - message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_INIT); + message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, UDP_INIT); if (message_p == NULL) { return -1; @@ -184,7 +184,7 @@ NwGtpv1uRcT gtpv1u_eNB_send_udp_msg( // Create and alloc new message MessageDef *message_p = NULL; udp_data_req_t *udp_data_req_p = NULL; - message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, UDP_DATA_REQ); if (message_p) { #if defined(LOG_GTPU) && LOG_GTPU > 0 @@ -285,7 +285,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( //ue_context_p->ue_context.handover_info->state = HO_END_MARKER; MessageDef *msg; // Configure end marker - msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_END_MARKER_REQ); + msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_REQ); GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len); memcpy(>PV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len); GTPV1U_ENB_END_MARKER_REQ(msg).length = buffer_len; @@ -358,7 +358,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) { MessageDef *msg; // Configure target - msg = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DATA_FORWARDING_REQ); + msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_REQ); GTPV1U_ENB_DATA_FORWARDING_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + buffer_len); memcpy(>PV1U_ENB_DATA_FORWARDING_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], buffer, buffer_len); GTPV1U_ENB_DATA_FORWARDING_REQ(msg).length = buffer_len; @@ -1122,7 +1122,7 @@ int gtpv1u_delete_s1u_tunnel( hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; teid_t teid_eNB = 0; int erab_index = 0; - message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_ENB_DELETE_TUNNEL_RESP); + message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_DELETE_TUNNEL_RESP); GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti; GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).status = 0; hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)>pv1u_ue_data_p); @@ -1289,7 +1289,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { itti_receive_msg(TASK_GTPV1_U, &received_message_p); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN); DevAssert(received_message_p != NULL); - instance = ITTI_MSG_INSTANCE(received_message_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(received_message_p); //msg_name_p = ITTI_MSG_NAME(received_message_p); switch (ITTI_MSG_ID(received_message_p)) { diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c index f13bf13794..19d2440a95 100644 --- a/openair3/GTPV1-U/gtpv1u_gNB.c +++ b/openair3/GTPV1-U/gtpv1u_gNB.c @@ -38,6 +38,7 @@ #include "NwGtpv1uPrivate.h" #include "NwLog.h" #include "gtpv1u_eNB_defs.h" +#include "gtpv1u_gNB_defs.h" #include "gtpv1_u_messages_types.h" #include "udp_eNB_task.h" #include "common/utils/LOG/log.h" @@ -45,7 +46,6 @@ #include "COMMON/platform_constants.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" -#include "gtpv1u_eNB_defs.h" #include "gtpv1u_eNB_task.h" #include "gtpv1u_gNB_task.h" #include "rrc_eNB_GTPV1U.h" @@ -309,3 +309,514 @@ void *gtpv1u_gNB_task(void *args) { return NULL; } +int nr_gtpv1u_gNB_init(void) { + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + NwGtpv1uUlpEntityT ulp; + NwGtpv1uUdpEntityT udp; + NwGtpv1uLogMgrEntityT log; + NwGtpv1uTimerMgrEntityT tmr; + // enb_properties_p = enb_config_get()->properties[0]; + RC.nr_gtpv1u_data_g = (nr_gtpv1u_data_t *)calloc(sizeof(nr_gtpv1u_data_t),1); + LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.nr_gtpv1u_data_g); + + /* Initialize UE hashtable */ + RC.nr_gtpv1u_data_g->ue_mapping = hashtable_create (32, NULL, NULL); + AssertFatal(RC.nr_gtpv1u_data_g->ue_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create returned %p\n", RC.gtpv1u_data_g->ue_mapping); + RC.nr_gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL); + AssertFatal(RC.nr_gtpv1u_data_g->teid_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create\n"); + // RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U; + //gtpv1u_data_g.udp_data; + RC.nr_gtpv1u_data_g->seq_num = 0; + RC.nr_gtpv1u_data_g->restart_counter = 0; + + /* Initializing GTPv1-U stack */ + if ((rc = nwGtpv1uInitialize(&RC.nr_gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc); + return -1; + } + + if ((rc = nwGtpv1uSetLogLevel(RC.nr_gtpv1u_data_g->gtpv1u_stack, + NW_LOG_LEVEL_DEBG)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "Failed to setup loglevel for stack %x\n", rc); + return -1; + } + + /* Set the ULP API callback. Called once message have been processed by the + * nw-gtpv1u stack. + */ + ulp.ulpReqCallback = gtpv1u_gNB_process_stack_req; + memset((void *)&(ulp.hUlp), 0, sizeof(NwGtpv1uUlpHandleT)); + + if ((rc = nwGtpv1uSetUlpEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetUlpEntity: %x", rc); + return -1; + } + + /* nw-gtpv1u stack requires an udp callback to send data over UDP. + * We provide a wrapper to UDP task. + */ + udp.udpDataReqCallback = gtpv1u_eNB_send_udp_msg; + memset((void *)&(udp.hUdp), 0, sizeof(NwGtpv1uUdpHandleT)); + + if ((rc = nwGtpv1uSetUdpEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &udp)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetUdpEntity: %x", rc); + return -1; + } + + log.logReqCallback = gtpv1u_eNB_log_request; + memset((void *)&(log.logMgrHandle), 0, sizeof(NwGtpv1uLogMgrHandleT)); + + if ((rc = nwGtpv1uSetLogMgrEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &log)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetLogMgrEntity: %x", rc); + return -1; + } + + /* Timer interface is more complicated as both wrappers doesn't send a message + * to the timer task but call the timer API functions start/stop timer. + */ + tmr.tmrMgrHandle = 0; + tmr.tmrStartCallback = gtpv1u_start_timer_wrapper; + tmr.tmrStopCallback = gtpv1u_stop_timer_wrapper; + + if ((rc = nwGtpv1uSetTimerMgrEntity(RC.nr_gtpv1u_data_g->gtpv1u_stack, &tmr)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetTimerMgrEntity: %x", rc); + return -1; + } + +#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 + + if ((ret = gtpv1u_eNB_create_dump_socket()) < 0) { + return -1; + } + +#endif + LOG_D(GTPU, "Initializing GTPV1U interface for eNB: DONE\n"); + return 0; +} + +//----------------------------------------------------------------------------- +int +gtpv1u_create_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_gnb_create_tunnel_resp_t *const create_tunnel_resp_pP) +{ + /* Create a new nw-gtpv1-u stack req using API */ + NwGtpv1uUlpApiT stack_req; + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + /* Local tunnel end-point identifier */ + teid_t ngu_teid = 0; + nr_gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; + nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; + //MessageDef *message_p = NULL; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + int i; + pdusessionid_t pdusession_id = 0; + // int ipv4_addr = 0; + int ip_offset = 0; + in_addr_t in_addr; + int addrs_length_in_bytes= 0; + int loop_counter = 0; + int ret = 0; + MSC_LOG_RX_MESSAGE( + MSC_GTPU_GNB, + MSC_RRC_GNB, + NULL,0, + MSC_AS_TIME_FMT" CREATE_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u psid %u upf-ngu teid %u", + 0,0,create_tunnel_req_pP->rnti, instanceP, + create_tunnel_req_pP->num_tunnels, create_tunnel_req_pP->pdusession_id[0], + create_tunnel_req_pP->upf_NGu_teid[0]); + create_tunnel_resp_pP->rnti = create_tunnel_req_pP->rnti; + create_tunnel_resp_pP->status = 0; + create_tunnel_resp_pP->num_tunnels = 0; + + for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { + ip_offset = 0; + loop_counter = 0; + pdusession_id = create_tunnel_req_pP->pdusession_id[i]; + LOG_D(GTPU, "Rx GTPV1U_GNB_CREATE_TUNNEL_REQ ue rnti %x pdu session id %u\n", + create_tunnel_req_pP->rnti, pdusession_id); + memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); + stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT; + + do { + ngu_teid = gtpv1u_new_teid(); + LOG_D(GTPU, "gtpv1u_create_ngu_tunnel() 0x%x %u(dec)\n", ngu_teid, ngu_teid); + stack_req.apiInfo.createTunnelEndPointInfo.teid = ngu_teid; + stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0; + stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0; + rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req); + LOG_D(GTPU, ".\n"); + loop_counter++; + } while (rc != NW_GTPV1U_OK && loop_counter < 10); + + if ( rc != NW_GTPV1U_OK && loop_counter == 10 ) { + LOG_E(GTPU,"NwGtpv1uCreateTunnelEndPoint failed 10 times,start next loop\n"); + ret = -1; + continue; + } + + //----------------------- + // PDCP->GTPV1U mapping + //----------------------- + hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, (void **)>pv1u_ue_data_p); + + if ((hash_rc == HASH_TABLE_KEY_NOT_EXISTS) || (hash_rc == HASH_TABLE_OK)) { + if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { + gtpv1u_ue_data_p = calloc (1, sizeof(gtpv1u_ue_data_t)); + hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_p); + AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable"); + } + + gtpv1u_ue_data_p->ue_id = create_tunnel_req_pP->rnti; + gtpv1u_ue_data_p->instance_id = 0; // TO DO + memcpy(&create_tunnel_resp_pP->gnb_addr.buffer, + &RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up, + sizeof (in_addr_t)); + + LOG_I(GTPU,"Configured GTPu address : %x\n",RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up); + create_tunnel_resp_pP->gnb_addr.length = sizeof (in_addr_t); + addrs_length_in_bytes = create_tunnel_req_pP->upf_addr[i].length / 8; + AssertFatal((addrs_length_in_bytes == 4) || + (addrs_length_in_bytes == 16) || + (addrs_length_in_bytes == 20), + "Bad transport layer address length %d (bits) %d (bytes)", + create_tunnel_req_pP->upf_addr[i].length, addrs_length_in_bytes); + + if ((addrs_length_in_bytes == 4) || + (addrs_length_in_bytes == 20)) { + in_addr = *((in_addr_t *)create_tunnel_req_pP->upf_addr[i].buffer); + ip_offset = 4; + gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip_addr = in_addr; + } + + if ((addrs_length_in_bytes == 16) || + (addrs_length_in_bytes == 20)) { + memcpy(gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip6_addr.s6_addr, + &create_tunnel_req_pP->upf_addr[i].buffer[ip_offset], + 16); + } + + gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].state = BEARER_IN_CONFIG; + gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].teid_gNB = ngu_teid; + gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session = stack_req.apiInfo.createTunnelEndPointInfo.hStackSession; + gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].teid_upf = create_tunnel_req_pP->upf_NGu_teid[i]; + gtpv1u_ue_data_p->num_bearers++; + create_tunnel_resp_pP->gnb_NGu_teid[i] = ngu_teid; + + LOG_I(GTPU,"Copied to create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + create_tunnel_resp_pP->gnb_addr.buffer[0], + create_tunnel_resp_pP->gnb_addr.buffer[1], + create_tunnel_resp_pP->gnb_addr.buffer[2], + create_tunnel_resp_pP->gnb_addr.buffer[3], + create_tunnel_resp_pP->gnb_addr.length, + create_tunnel_resp_pP->gnb_NGu_teid[i]); + } else { + create_tunnel_resp_pP->gnb_NGu_teid[i] = 0; + create_tunnel_resp_pP->status = 0xFF; + } + + create_tunnel_resp_pP->pdusession_id[i] = pdusession_id; + create_tunnel_resp_pP->num_tunnels += 1; + //----------------------- + // GTPV1U->PDCP mapping + //----------------------- + hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, (void **)>pv1u_teid_data_p); + + if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { + gtpv1u_teid_data_p = calloc (1, sizeof(nr_gtpv1u_teid_data_t)); + gtpv1u_teid_data_p->gnb_id = 0; // TO DO + gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti; + gtpv1u_teid_data_p->pdu_session_id = pdusession_id; + hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, gtpv1u_teid_data_p); + AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting teid mapping in GTPV1U hashtable"); + } else { + create_tunnel_resp_pP->gnb_NGu_teid[i] = 0; + create_tunnel_resp_pP->status = 0xFF; + } + } + + MSC_LOG_TX_MESSAGE( + MSC_GTPU_GNB, + MSC_RRC_GNB, + NULL,0, + "0 GTPV1U_GNB_CREATE_TUNNEL_RESP rnti %x teid %x", + create_tunnel_resp_pP->rnti, + ngu_teid); + LOG_D(GTPU, "Tx GTPV1U_GNB_CREATE_TUNNEL_RESP ue rnti %x status %d\n", + create_tunnel_req_pP->rnti, + create_tunnel_resp_pP->status); + //return 0; + return ret; +} + +int gtpv1u_update_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +) { + /* Local tunnel end-point identifier */ + teid_t ngu_teid = 0; + nr_gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; + nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; + nr_gtpv1u_ue_data_t *gtpv1u_ue_data_new_p = NULL; + //MessageDef *message_p = NULL; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + int i,j; + uint8_t bearers_num = 0,bearers_total = 0; + //----------------------- + // PDCP->GTPV1U mapping + //----------------------- + hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti, (void **)>pv1u_ue_data_p); + + if(hash_rc != HASH_TABLE_OK) { + LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti); + return -1; + } + + gtpv1u_ue_data_new_p = calloc (1, sizeof(nr_gtpv1u_ue_data_t)); + memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(nr_gtpv1u_ue_data_t)); + gtpv1u_ue_data_new_p->ue_id = create_tunnel_req_pP->rnti; + hash_rc = hashtable_insert(RC.nr_gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p); + + //AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable"); + if ( hash_rc != HASH_TABLE_OK ) { + LOG_E(GTPU,"Failed to insert ue_mapping(rnti=%x) in GTPV1U hashtable\n",create_tunnel_req_pP->rnti); + return -1; + } else { + LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n", + create_tunnel_req_pP->rnti); + } + + hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, prior_rnti); + LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n", + prior_rnti); + //----------------------- + // GTPV1U->PDCP mapping + //----------------------- + bearers_total =gtpv1u_ue_data_new_p->num_bearers; + + for(j = 0; jbearers[j].state != BEARER_IN_CONFIG) + continue; + + bearers_num++; + + for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { + if(j == (create_tunnel_req_pP->pdusession_id[i]-GTPV1U_BEARER_OFFSET)) + break; + } + + if(i < create_tunnel_req_pP->num_tunnels) { + ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB; + hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid, (void **)>pv1u_teid_data_p); + + if (hash_rc == HASH_TABLE_OK) { + gtpv1u_teid_data_p->ue_id = create_tunnel_req_pP->rnti; + gtpv1u_teid_data_p->pdu_session_id = create_tunnel_req_pP->pdusession_id[i]; + LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n", + ngu_teid,prior_rnti,create_tunnel_req_pP->rnti); + } else { + LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", ngu_teid); + } + } else { + ngu_teid = gtpv1u_ue_data_new_p->bearers[j].teid_gNB; + hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, ngu_teid); + + if (hash_rc != HASH_TABLE_OK) { + LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, ngu_teid); + } + + gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN; + gtpv1u_ue_data_new_p->num_bearers--; + LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n", + ngu_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);; + } + + if(bearers_num > bearers_total) + break; + } + + return 0; +} + +//----------------------------------------------------------------------------- +int gtpv1u_delete_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_delete_tunnel_req_t *const req_pP) { + NwGtpv1uUlpApiT stack_req; + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + MessageDef *message_p = NULL; + nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + teid_t teid_gNB = 0; + int pdusession_index = 0; + message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_GNB_DELETE_TUNNEL_RESP); + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti = req_pP->rnti; + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status = 0; + hash_rc = hashtable_get(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti, (void **)>pv1u_ue_data_p); + + if (hash_rc == HASH_TABLE_OK) { + for (pdusession_index = 0; pdusession_index < req_pP->num_pdusession; pdusession_index++) { + teid_gNB = gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB; + LOG_D(GTPU, "Rx GTPV1U_ENB_DELETE_TUNNEL user rnti %x eNB S1U teid %u eps bearer id %u\n", + req_pP->rnti, teid_gNB, req_pP->pdusession_id[pdusession_index]); + { + memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT)); + stack_req.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT; + LOG_D(GTPU, "gtpv1u_delete_ngu_tunnel pdusession %u %u\n", + req_pP->pdusession_id[pdusession_index], + teid_gNB); + stack_req.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle = + gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB_stack_session; + rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req); + LOG_D(GTPU, ".\n"); + } + + if (rc != NW_GTPV1U_OK) { + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status |= 0xFF; + LOG_E(GTPU, "NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT failed"); + } + + //----------------------- + // PDCP->GTPV1U mapping + //----------------------- + gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].state = BEARER_DOWN; + gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_gNB = 0; + gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].teid_upf = 0; + gtpv1u_ue_data_p->bearers[req_pP->pdusession_id[pdusession_index] - GTPV1U_BEARER_OFFSET].upf_ip_addr = 0; + gtpv1u_ue_data_p->num_bearers -= 1; + + if (gtpv1u_ue_data_p->num_bearers == 0) { + hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->ue_mapping, req_pP->rnti); + LOG_D(GTPU, "Removed user rnti %x,no more bearers configured\n", req_pP->rnti); + } + + //----------------------- + // GTPV1U->PDCP mapping + //----------------------- + hash_rc = hashtable_remove(RC.nr_gtpv1u_data_g->teid_mapping, teid_gNB); + + if (hash_rc != HASH_TABLE_OK) { + LOG_D(GTPU, "Removed user rnti %x , gNB NGU teid %u not found\n", req_pP->rnti, teid_gNB); + } + } + }// else silently do nothing + + LOG_D(GTPU, "Tx GTPV1U_GNB_DELETE_TUNNEL_RESP user rnti %x gNB NGU teid %u status %u\n", + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti, + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).gnb_NGu_teid, + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).status); + MSC_LOG_TX_MESSAGE( + MSC_GTPU_GNB, + MSC_RRC_GNB, + NULL,0, + "0 GTPV1U_GNB_DELETE_TUNNEL_RESP rnti %x teid %x", + GTPV1U_GNB_DELETE_TUNNEL_RESP(message_p).rnti, + teid_gNB); + return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p); +} + +//----------------------------------------------------------------------------- +static int gtpv1u_gNB_send_init_udp(const Gtpv1uNGReq *req) { + // Create and alloc new message + MessageDef *message_p; + struct in_addr addr= {0}; + message_p = itti_alloc_new_message(TASK_GTPV1_U, 0, UDP_INIT); + + if (message_p == NULL) { + return -1; + } + + UDP_INIT(message_p).port = req->gnb_port_for_NGu_up; + addr.s_addr = req->gnb_ip_address_for_NGu_up; + UDP_INIT(message_p).address = inet_ntoa(addr); + LOG_I(GTPU, "Tx UDP_INIT IP addr %s (%x)\n", UDP_INIT(message_p).address,UDP_INIT(message_p).port); + MSC_LOG_EVENT( + MSC_GTPU_ENB, + "0 UDP bind %s:%u", + UDP_INIT(message_p).address, + UDP_INIT(message_p).port); + return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p); +} + +static int gtpv1u_ng_req( + const instance_t instanceP, + const Gtpv1uNGReq *const req) { + memcpy(&RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up, + &req->gnb_ip_address_for_NGu_up, + sizeof (req->gnb_ip_address_for_NGu_up)); + gtpv1u_gNB_send_init_udp(req); + return 0; +} + +//----------------------------------------------------------------------------- +void *gtpv1u_gNB_process_itti_msg(void *notUsed) { + /* Trying to fetch a message from the message queue. + * If the queue is empty, this function will block till a + * message is sent to the task. + */ + instance_t instance; + MessageDef *received_message_p = NULL; + int rc = 0; + itti_receive_msg(TASK_GTPV1_U, &received_message_p); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_IN); + DevAssert(received_message_p != NULL); + instance = received_message_p->ittiMsgHeader.originInstance; + + switch (ITTI_MSG_ID(received_message_p)) { + case GTPV1U_GNB_NG_REQ: + gtpv1u_ng_req(instance, &received_message_p->ittiMsg.gtpv1uNGReq); + break; + + case GTPV1U_GNB_DELETE_TUNNEL_REQ: + gtpv1u_delete_ngu_tunnel(instance, &received_message_p->ittiMsg.NRGtpv1uDeleteTunnelReq); + break; + + case TERMINATE_MESSAGE: { + if (RC.nr_gtpv1u_data_g->ue_mapping != NULL) { + hashtable_destroy (&(RC.nr_gtpv1u_data_g->ue_mapping)); + } + + if (RC.nr_gtpv1u_data_g->teid_mapping != NULL) { + hashtable_destroy (&(RC.nr_gtpv1u_data_g->teid_mapping)); + } + + LOG_W(GTPU, " *** Exiting GTPU thread\n"); + itti_exit_task(); + } + break; + + case TIMER_HAS_EXPIRED: + nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg); + break; + + default: { + LOG_E(GTPU, "Unkwnon message ID %d:%s\n", + ITTI_MSG_ID(received_message_p), + ITTI_MSG_NAME(received_message_p)); + } + break; + } + + rc = itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p); + AssertFatal(rc == EXIT_SUCCESS, "Failed to free memory (%d)!\n", rc); + received_message_p = NULL; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_ENB_TASK, VCD_FUNCTION_OUT); + return NULL; +} + +void *nr_gtpv1u_gNB_task(void *args) { + int rc = 0; + rc = nr_gtpv1u_gNB_init(); + AssertFatal(rc == 0, "gtpv1u_gNB_init Failed"); + itti_mark_task_ready(TASK_GTPV1_U); + MSC_START_USE(); + + while(1) { + (void) gtpv1u_gNB_process_itti_msg (NULL); + } + + return NULL; +} diff --git a/openair3/GTPV1-U/gtpv1u_gNB_defs.h b/openair3/GTPV1-U/gtpv1u_gNB_defs.h new file mode 100644 index 0000000000..ddc8b4445e --- /dev/null +++ b/openair3/GTPV1-U/gtpv1u_gNB_defs.h @@ -0,0 +1,116 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file gtpv1u_gNB_defs.h + * \brief + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#include "hashtable.h" +#include "NR_asn_constant.h" + +#ifndef GTPV1U_GNB_DEFS_H_ +#define GTPV1U_GNB_DEFS_H_ + +#include "NwGtpv1u.h" + +#define GTPV1U_UDP_PORT (2152) + +#define NR_GTPV1U_MAX_BEARERS_ID (max_val_NR_DRB_Identity - 3) + +#define GTPV1U_SOURCE_GNB (0) +#define GTPV1U_TARGET_GNB (1) +#define GTPV1U_MSG_FROM_SOURCE_GNB (0) +#define GTPV1U_MSG_FROM_UPF (1) + + +typedef struct nr_gtpv1u_teid_data_s { + /* UE identifier for oaisim stack */ + module_id_t gnb_id; + rnti_t ue_id; + pdusessionid_t pdu_session_id; +} nr_gtpv1u_teid_data_t; + + +typedef struct nr_gtpv1u_bearer_s { + /* TEID used in dl and ul */ + teid_t teid_gNB; ///< gNB TEID + uintptr_t teid_gNB_stack_session; ///< gNB TEID + teid_t teid_upf; ///< Remote TEID + in_addr_t upf_ip_addr; + struct in6_addr upf_ip6_addr; + teid_t teid_tgNB; + in_addr_t tgnb_ip_addr; ///< target gNB ipv4 + struct in6_addr tgnb_ip6_addr; ///< target gNB ipv6 + tcp_udp_port_t port; + //NwGtpv1uStackSessionHandleT stack_session; + bearer_state_t state; +} nr_gtpv1u_bearer_t; + +typedef struct nr_gtpv1u_ue_data_s { + /* UE identifier for oaisim stack */ + rnti_t ue_id; + + /* Unique identifier used between PDCP and GTP-U to distinguish UEs */ + uint32_t instance_id; + int num_bearers; + /* Bearer related data. + * Note that the first LCID available for data is 3 and we fixed the maximum + * number of e-rab per UE to be (32 [id range]), max RB is 11. The real rb id will 3 + rab_id (3..32). + */ + nr_gtpv1u_bearer_t bearers[NR_GTPV1U_MAX_BEARERS_ID]; + + //RB_ENTRY(gtpv1u_ue_data_s) gtpv1u_ue_node; +} nr_gtpv1u_ue_data_t; + +typedef struct nr_gtpv1u_data_s { + /* nwgtpv1u stack internal data */ + NwGtpv1uStackHandleT gtpv1u_stack; + + /* RB tree of UEs */ + hash_table_t *ue_mapping; // PDCP->GTPV1U + hash_table_t *teid_mapping; // GTPV1U -> PDCP + + //RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head; + /* Local IP address to use */ + in_addr_t gnb_ip_address_for_NGu_up; + /* UDP internal data */ + //udp_data_t udp_data; + + uint16_t seq_num; + uint8_t restart_counter; + +#ifdef GTPU_IN_KERNEL + char *interface_name; + int interface_index; + + struct iovec *malloc_ring; + void *sock_mmap_ring[16]; + int sock_desc[16]; // indexed by marking +#endif +} nr_gtpv1u_data_t; + + +#endif /* GTPV1U_GNB_DEFS_H_ */ diff --git a/openair3/GTPV1-U/gtpv1u_gNB_task.h b/openair3/GTPV1-U/gtpv1u_gNB_task.h index 42fae7a714..fcfaa90304 100644 --- a/openair3/GTPV1-U/gtpv1u_gNB_task.h +++ b/openair3/GTPV1-U/gtpv1u_gNB_task.h @@ -32,6 +32,20 @@ int gtpv1u_gNB_init(void); void *gtpv1u_gNB_task(void *args); +void *nr_gtpv1u_gNB_task(void *args); + +int +gtpv1u_create_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t * const create_tunnel_req_pP, + gtpv1u_gnb_create_tunnel_resp_t * const create_tunnel_resp_pP); + +int +gtpv1u_update_ngu_tunnel( + const instance_t instanceP, + const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, + const rnti_t prior_rnti +); #endif /* GTPV1U_GNB_TASK_H_ */ diff --git a/openair3/M3AP/m3ap_MCE.c b/openair3/M3AP/m3ap_MCE.c index dec9b96897..9362c8fcb6 100644 --- a/openair3/M3AP/m3ap_MCE.c +++ b/openair3/M3AP/m3ap_MCE.c @@ -136,7 +136,7 @@ void m3ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_associa //dump_trees_m3(); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + M3AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -229,7 +229,7 @@ int m3ap_MCE_init_sctp (m3ap_MCE_instance_t *instance_p, sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M3AP_MCE, SCTP_INIT_MSG_MULTI_REQ); + message = itti_alloc_new_message (TASK_M3AP_MCE, 0, SCTP_INIT_MSG_MULTI_REQ); sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = mce_port_for_M3C; sctp_init->ppid = M3AP_SCTP_PPID; @@ -263,7 +263,7 @@ static void m3ap_MCE_register_MCE(m3ap_MCE_instance_t *instance_p, m3ap_MCE_data_t *m3ap_mce_data = NULL; DevAssert(instance_p != NULL); DevAssert(target_MCE_ip_address != NULL); - message = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI); + message = itti_alloc_new_message(TASK_M3AP_MCE, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI); sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; sctp_new_association_req->port = mce_port_for_M3C; sctp_new_association_req->ppid = M3AP_SCTP_PPID; @@ -313,7 +313,7 @@ void m3ap_MCE_handle_register_MCE(instance_t instance, DevCheck(new_instance->tac == m3ap_register_MCE->tac, new_instance->tac, m3ap_register_MCE->tac, 0); DevCheck(new_instance->mcc == m3ap_register_MCE->mcc, new_instance->mcc, m3ap_register_MCE->mcc, 0); DevCheck(new_instance->mnc == m3ap_register_MCE->mnc, new_instance->mnc, m3ap_register_MCE->mnc, 0); - M3AP_WARN("MCE[%d] already registered\n", instance); + M3AP_WARN("MCE[%ld] already registered\n", instance); } else { new_instance = calloc(1, sizeof(m3ap_MCE_instance_t)); DevAssert(new_instance != NULL); @@ -357,7 +357,7 @@ void m3ap_MCE_handle_register_MCE(instance_t instance, new_instance->mce_port_for_M3C = m3ap_register_MCE->mme_port_for_M3C; /* Add the new instance to the list of MCE (meaningfull in virtual mode) */ m3ap_MCE_insert_new_instance(new_instance); - M3AP_INFO("Registered new MCE[%d] and %s MCE id %u\n", + M3AP_INFO("Registered new MCE[%ld] and %s MCE id %u\n", instance, m3ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home", m3ap_register_MCE->MCE_id); @@ -370,7 +370,7 @@ void m3ap_MCE_handle_register_MCE(instance_t instance, return; } - M3AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n", + M3AP_INFO("MCE[%ld] MCE id %u acting as a listner (server)\n", instance, m3ap_register_MCE->MCE_id); } } @@ -397,7 +397,7 @@ void m3ap_MCE_handle_sctp_init_msg_multi_cnf( /* Trying to connect to the provided list of MCE ip address */ for (index = 0; index < instance->nb_m3; index++) { - M3AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n", + M3AP_INFO("MCE[%ld] MCE id %u acting as an initiator (client)\n", instance_id, instance->MCE_id); m3ap_MCE_register_MCE(instance, &instance->target_mme_m3_ip_address[index], @@ -537,7 +537,7 @@ void *m3ap_MCE_task(void *arg) { switch (ITTI_MSG_ID(received_msg)) { case MESSAGE_TEST: // LOG_W(M3AP,"MCE Received Test Message ... TODO\n"); -// //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP, MESSAGE_TEST); +// //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP, 0, MESSAGE_TEST); // //itti_send_msg_to_task(TASK_M2AP_ENB, 1/*ctxt_pP->module_id*/, message_p); // // asn_dec_rval_t dec_ret; @@ -577,78 +577,78 @@ void *m3ap_MCE_task(void *arg) { break; case M3AP_SUBFRAME_PROCESS: - m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); + m3ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); break; case M3AP_REGISTER_MCE_REQ: LOG_I(M3AP,"MCE Received M3AP_REGISTER_MCE_REQ Message\n"); - m3ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MCE_handle_register_MCE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_REGISTER_MCE_REQ(received_msg)); break; case M3AP_MBMS_SESSION_START_RESP: LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_START_RESP Message\n"); - MCE_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MCE_send_MBMS_SESSION_START_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_MBMS_SESSION_START_RESP(received_msg)); break; case M3AP_MBMS_SESSION_STOP_RESP: LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_STOP_RESP Message\n"); - MCE_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MCE_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_MBMS_SESSION_START_RESP(received_msg)); break; case M3AP_MBMS_SESSION_UPDATE_RESP: LOG_I(M3AP,"MCE M3AP_MBMS_SESSION_UPDATE_RESP Message\n"); - //MCE_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + //MCE_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), //&M3AP_MBMS_SESSION_START_RESP(received_msg)); break; // case M3AP_HANDOVER_REQ: -// m3ap_eNB_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_eNB_handle_handover_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_HANDOVER_REQ(received_msg)); // break; // // case M3AP_HANDOVER_REQ_ACK: -// m3ap_eNB_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_eNB_handle_handover_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_HANDOVER_REQ_ACK(received_msg)); // break; // // case M3AP_UE_CONTEXT_RELEASE: -// m3ap_eNB_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_eNB_ue_context_release(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_UE_CONTEXT_RELEASE(received_msg)); // break; // case SCTP_INIT_MSG_MULTI_CNF: LOG_D(M3AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n"); - m3ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); break; case SCTP_NEW_ASSOCIATION_RESP: LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n"); - m3ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MCE_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_NEW_ASSOCIATION_IND: LOG_D(M3AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n"); - m3ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MCE_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind); break; case SCTP_DATA_IND: LOG_D(M3AP,"MCE Received SCTP_DATA_IND Message\n"); - m3ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MCE_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; diff --git a/openair3/M3AP/m3ap_MCE_handler.c b/openair3/M3AP/m3ap_MCE_handler.c index e733af28db..21d10d1b04 100644 --- a/openair3/M3AP/m3ap_MCE_handler.c +++ b/openair3/M3AP/m3ap_MCE_handler.c @@ -108,7 +108,7 @@ int m3ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre } /* Calling the right handler */ - LOG_I(M3AP, "Calling handler with instance %d\n",instance); + LOG_I(M3AP, "Calling handler with instance %ld\n",instance); ret = (*m3ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); diff --git a/openair3/M3AP/m3ap_MCE_interface_management.c b/openair3/M3AP/m3ap_MCE_interface_management.c index 2694846526..fb54579258 100644 --- a/openair3/M3AP/m3ap_MCE_interface_management.c +++ b/openair3/M3AP/m3ap_MCE_interface_management.c @@ -74,7 +74,7 @@ int MCE_handle_MBMS_SESSION_START_REQUEST(instance_t instance, // // container = &pdu->choice.initiatingMessage.value.choice.SessionStartRequest; - message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_START_REQ); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, M3AP_MBMS_SESSION_START_REQ); // // /* M3 Setup Request == Non UE-related procedure -> stream 0 */ @@ -248,7 +248,7 @@ int MCE_handle_MBMS_SESSION_STOP_REQUEST(instance_t instance, //MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id); //}else //MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id); - message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_STOP_REQ); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, M3AP_MBMS_SESSION_STOP_REQ); // // /* M3 Setup Request == Non UE-related procedure -> stream 0 */ @@ -361,7 +361,7 @@ int MCE_handle_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, //MCE_send_MBMS_SESSION_STOP_RESPONSE(instance,assoc_id); //}else //MCE_send_MBMS_SESSION_STOP_FAILURE(instance,assoc_id); - message_p = itti_alloc_new_message(TASK_M3AP_MCE, M3AP_MBMS_SESSION_UPDATE_REQ); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, M3AP_MBMS_SESSION_UPDATE_REQ); // // /* M3 Setup Request == Non UE-related procedure -> stream 0 */ @@ -711,7 +711,7 @@ int MCE_handle_M3_SETUP_RESPONSE(instance_t instance, //int num_cells_to_activate = 0; //M3AP_Cells_to_be_Activated_List_Item_t *cell; - MessageDef *msg_p = itti_alloc_new_message (TASK_M3AP_MCE, M3AP_SETUP_RESP); + MessageDef *msg_p = itti_alloc_new_message (TASK_M3AP_MCE, 0, M3AP_SETUP_RESP); // LOG_D(M3AP, "M3AP: M3Setup-Resp: protocolIEs.list.count %d\n", // in->protocolIEs.list.count); diff --git a/openair3/M3AP/m3ap_MCE_management_procedures.c b/openair3/M3AP/m3ap_MCE_management_procedures.c index 32901ca869..065d4b9616 100644 --- a/openair3/M3AP/m3ap_MCE_management_procedures.c +++ b/openair3/M3AP/m3ap_MCE_management_procedures.c @@ -116,7 +116,7 @@ void dump_trees_m3(void) m3ap_MCE_instance_t *zz; STAILQ_FOREACH(zz, &m3ap_MCE_internal_data.m3ap_MCE_instances_head, m3ap_MCE_entries) { -printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +printf("here comes the tree (instance %ld):\n---------------------------------------------\n", zz->instance); dump_tree_m3(zz->m3ap_mce_head.rbh_root); printf("---------------------------------------------\n"); } diff --git a/openair3/M3AP/m3ap_MME.c b/openair3/M3AP/m3ap_MME.c index fbfe6e1327..4d73caff23 100644 --- a/openair3/M3AP/m3ap_MME.c +++ b/openair3/M3AP/m3ap_MME.c @@ -105,7 +105,7 @@ void m3ap_MME_handle_sctp_association_resp(instance_t instance, sctp_new_associa DevAssert(sctp_new_association_resp != NULL); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - LOG_W(M3AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + LOG_W(M3AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -233,7 +233,7 @@ int m3ap_MME_init_sctp (m3ap_MME_instance_t *instance_p, sctp_init_t *sctp_init = NULL; DevAssert(instance_p != NULL); DevAssert(local_ip_addr != NULL); - message = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG_MULTI_REQ); + message = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG_MULTI_REQ); sctp_init = &message->ittiMsg.sctp_init_multi; sctp_init->port = mme_port_for_M3C; sctp_init->ppid = M3AP_SCTP_PPID; @@ -267,7 +267,7 @@ static void m3ap_MME_register_MME(m3ap_MME_instance_t *instance_p, // m3ap_MME_data_t *m3ap_mme_data = NULL; // DevAssert(instance_p != NULL); // DevAssert(target_MME_ip_address != NULL); - // message = itti_alloc_new_message(TASK_M3AP_MME, SCTP_NEW_ASSOCIATION_REQ_MULTI); + // message = itti_alloc_new_message(TASK_M3AP_MME, 0, SCTP_NEW_ASSOCIATION_REQ_MULTI); // sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi; // sctp_new_association_req->port = mme_port_for_M3C; // sctp_new_association_req->ppid = M3AP_SCTP_PPID; @@ -394,7 +394,7 @@ void m3ap_MME_handle_sctp_init_msg_multi_cnf( /* Trying to connect to the provided list of MME ip address */ for (index = 0; index < instance->nb_m3; index++) { - M3AP_INFO("MME[%d] MME id %u acting as an initiator (client)\n", + M3AP_INFO("MME[%ld] MME id %u acting as an initiator (client)\n", instance_id, instance->MME_id); m3ap_MME_register_MME(instance, &instance->target_mme_m3_ip_address[index], @@ -506,7 +506,7 @@ void MME_task_send_sctp_init_req(instance_t enb_id, m3ap_mme_sctp_req_t * m3ap_m MessageDef *message_p = NULL; - message_p = itti_alloc_new_message (TASK_M3AP_MME, SCTP_INIT_MSG); + message_p = itti_alloc_new_message (TASK_M3AP_MME, 0, SCTP_INIT_MSG); if(m3ap_mme_sctp_req==NULL) { LOG_I(M3AP, "M3AP_SCTP_REQ(create socket)\n"); message_p->ittiMsg.sctp_init.port = M3AP_PORT_NUMBER; @@ -555,7 +555,7 @@ void *m3ap_MME_task(void *arg) { switch (ITTI_MSG_ID(received_msg)) { case MESSAGE_TEST: LOG_W(M3AP,"MME Received MESSAGE_TEST Message\n"); - //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP_MME, MESSAGE_TEST); + //MessageDef * message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, MESSAGE_TEST); //itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p); break; case TERMINATE_MESSAGE: @@ -564,31 +564,31 @@ void *m3ap_MME_task(void *arg) { break; // case M3AP_SUBFRAME_PROCESS: -// m3ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg)); +// m3ap_check_timers(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // break; // // case M3AP_REGISTER_MME_REQ: // LOG_W(M3AP,"MME Received M3AP_REGISTER_MME_REQ Message\n"); -// m3ap_MME_handle_register_MME(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_MME_handle_register_MME(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_REGISTER_MME_REQ(received_msg)); // break; // case M3AP_MME_SCTP_REQ: - MME_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MME_task_send_sctp_init_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_MME_SCTP_REQ(received_msg)); break; case M3AP_SETUP_RESP: LOG_I(M3AP,"MME Received M3AP_SETUP_RESP Message\n"); - MME_send_M3_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MME_send_M3_SETUP_RESPONSE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_SETUP_RESP(received_msg)); break; // break; // // case M3AP_SETUP_FAILURE: // LOG_W(M3AP,"MME Received M3AP_SETUP_FAILURE Message\n"); -// MME_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// MME_send_M2_SETUP_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_SETUP_FAILURE(received_msg)); // break; // @@ -599,83 +599,83 @@ void *m3ap_MME_task(void *arg) { // case M3AP_MBMS_SESSION_START_REQ: LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_START_REQ Message\n"); - MME_send_MBMS_SESSION_START_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MME_send_MBMS_SESSION_START_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_MBMS_SESSION_START_REQ(received_msg)); break; // case M3AP_MBMS_SESSION_STOP_REQ: LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_STOP_REQ Message\n"); - MME_send_MBMS_SESSION_STOP_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + MME_send_MBMS_SESSION_STOP_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &M3AP_MBMS_SESSION_STOP_REQ(received_msg)); break; // case M3AP_MBMS_SESSION_UPDATE_REQ: LOG_I(M3AP,"MME Received M3AP_MBMS_SESSION_UPDATE_REQ Message\n"); - // MME_send_MBMS_SESSION_UPDATE_REQUEST(ITTI_MESSAGE_GET_INSTANCE(received_msg), + // MME_send_MBMS_SESSION_UPDATE_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_MBMS_SESSION_UPDATE_REQ(received_msg)); break; // // case M3AP_RESET: // LOG_W(M3AP,"MME Received M3AP_RESET Message\n"); -// MME_send_RESET(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// MME_send_RESET(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_RESET(received_msg)); // break; // // case M3AP_ENB_CONFIGURATION_UPDATE_ACK: // LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_ACK Message\n"); -// MME_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// MME_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg)); // break; // // case M3AP_ENB_CONFIGURATION_UPDATE_FAILURE: // LOG_W(M3AP,"MME Received M3AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n"); -// MME_send_ENB_CONFIGURATION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// MME_send_ENB_CONFIGURATION_UPDATE_FAILURE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg))// break; // // // case M3AP_MME_CONFIGURATION_UPDATE: // LOG_W(M3AP,"MME Received M3AP_MME_CONFIGURATION_UPDATE Message\n"); -// MME_send_MME_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// MME_send_MME_CONFIGURATION_UPDATE(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_MME_CONFIGURATION_UPDATE(received_msg)); // break; // // case M3AP_HANDOVER_REQ: -// m3ap_MME_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_MME_handle_handover_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_HANDOVER_REQ(received_msg)); // break; // // case M3AP_HANDOVER_REQ_ACK: -// m3ap_MME_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_MME_handle_handover_req_ack(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_HANDOVER_REQ_ACK(received_msg)); // break; // // case M3AP_UE_CONTEXT_RELEASE: -// m3ap_MME_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg), +// m3ap_MME_ue_context_release(ITTI_MSG_DESTINATION_INSTANCE(received_msg), // &M3AP_UE_CONTEXT_RELEASE(received_msg)); // break; // case SCTP_INIT_MSG_MULTI_CNF: LOG_E(M3AP,"MME Received SCTP_INIT_MSG_MULTI_CNF Message ... shoudn't be happening ... it doesn't at leaast with M2AP_MCEC\n"); - m3ap_MME_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MME_handle_sctp_init_msg_multi_cnf(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); break; case SCTP_NEW_ASSOCIATION_RESP: LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION_RESP Message\n"); - m3ap_MME_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MME_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); break; case SCTP_NEW_ASSOCIATION_IND: LOG_D(M3AP,"MME Received SCTP_NEW_ASSOCIATION Message\n"); - m3ap_MME_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MME_handle_sctp_association_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_ind); break; case SCTP_DATA_IND: LOG_D(M3AP,"MME Received SCTP_DATA_IND Message\n"); - m3ap_MME_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + m3ap_MME_handle_sctp_data_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_data_ind); break; diff --git a/openair3/M3AP/m3ap_MME_handler.c b/openair3/M3AP/m3ap_MME_handler.c index 9af8cbe14f..688e3937e1 100644 --- a/openair3/M3AP/m3ap_MME_handler.c +++ b/openair3/M3AP/m3ap_MME_handler.c @@ -108,7 +108,7 @@ int m3ap_MME_handle_message(instance_t instance, uint32_t assoc_id, int32_t stre } /* Calling the right handler */ - LOG_I(M3AP, "Calling handler with instance %d\n",instance); + LOG_I(M3AP, "Calling handler with instance %ld\n",instance); ret = (*m3ap_MME_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1]) (instance, assoc_id, stream, &pdu); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M3AP_M3AP_PDU, &pdu); diff --git a/openair3/M3AP/m3ap_MME_interface_management.c b/openair3/M3AP/m3ap_MME_interface_management.c index e5cb03cf26..ccdfa4fc5e 100644 --- a/openair3/M3AP/m3ap_MME_interface_management.c +++ b/openair3/M3AP/m3ap_MME_interface_management.c @@ -265,7 +265,7 @@ int MME_handle_MBMS_SESSION_START_RESPONSE(instance_t instance, int MCE_MBMS_M3AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_START_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME, 0,M3AP_MBMS_SESSION_START_RESP); //TODO LOG_D(M3AP, "M3AP: SessionStart-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -403,7 +403,7 @@ int MME_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance, int MCE_MBMS_M3AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_STOP_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME, 0,M3AP_MBMS_SESSION_STOP_RESP); //TODO LOG_D(M3AP, "M3AP: MBMSSessionStop-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); @@ -522,7 +522,7 @@ int MME_handle_M3_SETUP_REQUEST(instance_t instance, // assoc_id, stream); // } // - message_p = itti_alloc_new_message(TASK_M3AP_MME, M3AP_SETUP_REQ); + message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, M3AP_SETUP_REQ); //printf("M3AP_SETUP_REQ(message_p).assoc_id %d\n",M3AP_SETUP_REQ(message_p).assoc_id); // // /* assoc_id */ @@ -1055,7 +1055,7 @@ int MME_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance, int MCE_MBMS_M3AP_ID=-1; - MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME,M3AP_MBMS_SESSION_UPDATE_RESP); //TODO + MessageDef *msg_g = itti_alloc_new_message(TASK_M3AP_MME, 0,M3AP_MBMS_SESSION_UPDATE_RESP); //TODO LOG_D(M3AP, "M3AP: SessionUpdate-Resp: protocolIEs.list.count %d\n", in->protocolIEs.list.count); diff --git a/openair3/M3AP/m3ap_MME_management_procedures.c b/openair3/M3AP/m3ap_MME_management_procedures.c index 11d2924249..151aba04e4 100644 --- a/openair3/M3AP/m3ap_MME_management_procedures.c +++ b/openair3/M3AP/m3ap_MME_management_procedures.c @@ -116,7 +116,7 @@ void dump_mme_trees_m2(void) m3ap_MME_instance_t *zz; STAILQ_FOREACH(zz, &m3ap_MME_internal_data.m3ap_MME_instances_head, m3ap_MME_entries) { -printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance); +printf("here comes the tree (instance %ld):\n---------------------------------------------\n", zz->instance); dump_mme_tree_m2(zz->m3ap_mme_head.rbh_root); printf("---------------------------------------------\n"); } diff --git a/openair3/M3AP/m3ap_itti_messaging.c b/openair3/M3AP/m3ap_itti_messaging.c index b906747640..42e689343f 100644 --- a/openair3/M3AP/m3ap_itti_messaging.c +++ b/openair3/M3AP/m3ap_itti_messaging.c @@ -36,7 +36,7 @@ void m3ap_MCE_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -56,7 +56,7 @@ void m3ap_MCE_itti_send_sctp_close_association(instance_t instance, int32_t asso MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_M3AP_MCE, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_M3AP_MCE, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; @@ -70,7 +70,7 @@ void m3ap_MME_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -88,7 +88,7 @@ void m3ap_MME_itti_send_sctp_close_association(instance_t instance, int32_t asso MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_M3AP_MME, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_M3AP_MME, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; diff --git a/openair3/MME_APP/mme_app.c b/openair3/MME_APP/mme_app.c index 534aec8b34..5a32ddc98c 100644 --- a/openair3/MME_APP/mme_app.c +++ b/openair3/MME_APP/mme_app.c @@ -76,7 +76,7 @@ extern RAN_CONTEXT_t RC; // { // // M3AP registration // /* note: there is an implicit relationship between the data structure and the message name */ -// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_REGISTER_MCE_REQ); +// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_REGISTER_MCE_REQ); // //RCconfig_S1(msg_p, mce_id); // // //if (mce_id == 0) @@ -90,7 +90,7 @@ extern RAN_CONTEXT_t RC; // //if (NODE_IS_DU(node_type)) { // F1AP registration // // // configure F1AP here for F1C // // LOG_I(ENB_APP,"ngran_eNB_DU: Allocating ITTI message for F1AP_SETUP_REQ\n"); -// // msg_p = itti_alloc_new_message (TASK_ENB_APP, F1AP_SETUP_REQ); +// // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, F1AP_SETUP_REQ); // // RCconfig_DU_F1(msg_p, enb_id); // // // LOG_I(ENB_APP,"[eNB %d] eNB_app_register via F1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id)); @@ -99,7 +99,7 @@ extern RAN_CONTEXT_t RC; // //} // //else { // S1AP registration // // /* note: there is an implicit relationship between the data structure and the message name */ -// // msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ); +// // msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, S1AP_REGISTER_ENB_REQ); // // RCconfig_S1(msg_p, enb_id); // // // if (enb_id == 0) RCconfig_gtpu(); @@ -126,7 +126,7 @@ extern RAN_CONTEXT_t RC; // // for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { // { -// msg_p = itti_alloc_new_message (TASK_ENB_APP, X2AP_REGISTER_ENB_REQ); +// msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, X2AP_REGISTER_ENB_REQ); // RCconfig_X2(msg_p, mce_id); // itti_send_msg_to_task (TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); // register_mce_x2_pending++; @@ -146,7 +146,7 @@ extern RAN_CONTEXT_t RC; // for (mce_id = mce_id_start; (mce_id < mce_id_end) ; mce_id++) { // { // // LOG_W(MME_APP,"Register commes inside ...\n"); -// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_REGISTER_MCE_REQ); +// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M2AP_REGISTER_MCE_REQ); // //RCconfig_M2_MCE(msg_p, mce_id); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(mce_id), msg_p); // // LOG_W(MME_APP,"Register sent ...\n"); @@ -163,7 +163,7 @@ static uint32_t MME_app_handle_m3ap_setup_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_SETUP_RESP); + msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_SETUP_RESP); itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -187,7 +187,7 @@ static uint32_t MME_app_handle_m3ap_session_start_resp(instance_t instance){ // // uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MME_APP, M2AP_MBMS_SCHEDULING_INFORMATION); +// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M2AP_MBMS_SCHEDULING_INFORMATION); // itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -197,7 +197,7 @@ static uint32_t MME_app_send_m3ap_session_start_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_START_REQ); + msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_MBMS_SESSION_START_REQ); itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -206,7 +206,7 @@ static uint32_t MME_app_send_m3ap_session_start_req(instance_t instance){ // // //uint32_t mce_id=0; // MessageDef *msg_p; -// msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_STOP_REQ); +// msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_MBMS_SESSION_STOP_REQ); // itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); // // return 0; @@ -215,7 +215,7 @@ static uint32_t MME_app_send_m3ap_session_update_req(instance_t instance){ //uint32_t mce_id=0; MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_MME_APP, M3AP_MBMS_SESSION_UPDATE_REQ); + msg_p = itti_alloc_new_message (TASK_MME_APP, 0, M3AP_MBMS_SESSION_UPDATE_REQ); itti_send_msg_to_task (TASK_M3AP_MME, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p); return 0; @@ -263,7 +263,7 @@ void *MME_app_task(void *args_p) { do { // Wait for a message itti_receive_msg (TASK_MME_APP, &msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -297,7 +297,7 @@ void *MME_app_task(void *args_p) { // if (registered_mce == mce_nb) { // /* If all MCE are registered, start L2L1 task */ // // MessageDef *msg_init_p; - // // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE); + // // msg_init_p = itti_alloc_new_message (TASK_ENB_APP, 0, INITIALIZE_MESSAGE); // // itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); // } else { // LOG_W(MME_APP, " %d MCE not associated with a MME, retrying registration in %d seconds ...\n", @@ -341,7 +341,7 @@ void *MME_app_task(void *args_p) { // /* If all MCE cells are registered, start L2L1 task */ // MessageDef *msg_init_p; - // //msg_init_p = itti_alloc_new_message (TASK_MME_APP, INITIALIZE_MESSAGE); + // //msg_init_p = itti_alloc_new_message (TASK_MME_APP, 0, INITIALIZE_MESSAGE); // //itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p); // } else { @@ -365,7 +365,7 @@ void *MME_app_task(void *args_p) { case M3AP_DEREGISTERED_MCE_IND: //M3AP_DEREGISTERED_MCE_IND debería if (EPC_MODE_ENABLED) { - LOG_W(MME_APP, "[MCE %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), + LOG_W(MME_APP, "[MCE %ld] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), M3AP_DEREGISTERED_MCE_IND(msg_p).nb_mme); /* TODO handle recovering of registration */ } diff --git a/openair3/MME_APP/mme_config.c b/openair3/MME_APP/mme_config.c index 04dba67567..3b4074f553 100644 --- a/openair3/MME_APP/mme_config.c +++ b/openair3/MME_APP/mme_config.c @@ -94,7 +94,7 @@ int RCconfig_MME(void ) { if (address) { MessageDef *message; - AssertFatal((message = itti_alloc_new_message(TASK_MME_APP, M3AP_MME_SCTP_REQ))!=NULL,""); + AssertFatal((message = itti_alloc_new_message(TASK_MME_APP, 0, M3AP_MME_SCTP_REQ))!=NULL,""); M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv6 = 0; M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4 = 1; strcpy( M3AP_MME_SCTP_REQ (message).mme_m3_ip_address.ipv4_address, address); diff --git a/common/utils/itti_analyzer/libparser/file_type.c b/openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.c similarity index 57% rename from common/utils/itti_analyzer/libparser/file_type.c rename to openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.c index 04d66b7a08..5e1ff25151 100644 --- a/common/utils/itti_analyzer/libparser/file_type.c +++ b/openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.c @@ -19,35 +19,38 @@ * contact@openairinterface.org */ +/*! \file FGSAuthenticationResponse.c + +\brief authentication response procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + #include #include -#include #include +#include -#define G_LOG_DOMAIN ("PARSER") +#include "nas_log.h" -#include "file_type.h" +#include "FGSAuthenticationResponse.h" -int file_type_file_print(types_t *type, int indent, FILE *file) + +int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len) { - if (type == NULL) - return -1; - INDENTED(file, indent, fprintf(file, "\n")); - INDENTED(file, indent+4, fprintf(file, "Id .........: %d\n", type->id)); - INDENTED(file, indent+4, fprintf(file, "Name .......: %s\n", type->name)); - INDENTED(file, indent, fprintf(file, "\n")); + int encoded = 0; + int encode_result = 0; - return 0; + + if ((encode_result = + encode_authentication_response_parameter(&authentication_response->authenticationresponseparameter, + AUTHENTICATION_RESPONSE_PARAMETER_IEI, buffer + encoded, len - encoded)) < 0) //Return in case of error + return encode_result; + else + encoded += encode_result; + + return encoded; } -int file_type_hr_display(types_t *type, int indent) -{ - if (type == NULL) - return -1; - INDENTED(stdout, indent, printf("\n")); - INDENTED(stdout, indent+4, printf("Id .........: %d\n", type->id)); - INDENTED(stdout, indent+4, printf("Name .......: %s\n", type->name)); - INDENTED(stdout, indent, printf("\n")); - - return 0; -} diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.h b/openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.h new file mode 100644 index 0000000000..0acee3382f --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSAuthenticationResponse.h @@ -0,0 +1,66 @@ +/* + * 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 FGSAuthenticationResponse.h + +\brief authentication response procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "MessageType.h" +#include "AuthenticationResponseParameter.h" + +#ifndef FGS_AUTHENTICATION_RESPONSE_H_ +#define FGS_AUTHENTICATION_RESPONSE_H_ + +#define AUTHENTICATION_RESPONSE_PARAMETER_IEI 0x2d + +/* + * Message name: Identity response + * Description: This message is sent by the UE to the AMF to provide the requested identity. See table 8.2.22.1. + * Significance: dual + * Direction: UE to AMF + */ + +typedef struct fgs_authentication_response_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + AuthenticationResponseParameter authenticationresponseparameter; +} fgs_authentication_response_msg; + +int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_AUTHENTICATION_RESPONSE_H_) */ + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.c b/openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.c new file mode 100644 index 0000000000..4f8f6dd321 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.c @@ -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 + */ + +/*! \file FGSIdentityResponse.c + +\brief identity response procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include + +#include "nas_log.h" + +#include "FGSIdentityResponse.h" + + +int encode_identiy_response(fgs_identiy_response_msg *fgs_identity_reps, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + if ((encode_result = + encode_5gs_mobile_identity(&fgs_identity_reps->fgsmobileidentity, 0, buffer + + encoded, len - encoded)) < 0) //Return in case of error + return encode_result; + else + encoded += encode_result; + + return encoded; +} + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.h b/openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.h new file mode 100644 index 0000000000..431293e03e --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSIdentityResponse.h @@ -0,0 +1,65 @@ +/* + * 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 FGSIdentityResponse.h + +\brief identity response procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "FGSMobileIdentity.h" +#include "MessageType.h" + +#ifndef FGS_IDENTITY_RESPONSE_H_ +#define FGS_IDENTITY_RESPONSE_H_ + +/* + * Message name: Identity response + * Description: This message is sent by the UE to the AMF to provide the requested identity. See table 8.2.22.1. + * Significance: dual + * Direction: UE to AMF + */ + +typedef struct fgs_identiy_response_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + FGSMobileIdentity fgsmobileidentity; + +} fgs_identiy_response_msg; + +int encode_identiy_response(fgs_identiy_response_msg *fgs_identity_reps, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_IDENTITY_RESPONSE_H_) */ + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c new file mode 100644 index 0000000000..e0be56145f --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c @@ -0,0 +1,66 @@ +/* + * 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 FGSNASSecurityModeComplete.c + +\brief security mode complete procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include + +#include "nas_log.h" + +#include "FGSNASSecurityModeComplete.h" +#include "FGSMobileIdentity.h" +#include "FGCNasMessageContainer.h" + +int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + if ((encode_result = + encode_5gs_mobile_identity(&fgs_security_mode_comp->fgsmobileidentity, 0x77, buffer + + encoded, len - encoded)) < 0) { //Return in case of error + return encode_result; + } else { + encoded += encode_result; + if ((encode_result = + encode_fgc_nas_message_container(&fgs_security_mode_comp->fgsnasmessagecontainer, 0x71, buffer + + encoded, len - encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + } + + return encoded; +} + + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h new file mode 100644 index 0000000000..702dca3dc5 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h @@ -0,0 +1,65 @@ +/* + * 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 FGSNASSecurityModeComplete.h + +\brief security mode complete procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "FGSMobileIdentity.h" +#include "MessageType.h" +#include "FGCNasMessageContainer.h" + +#ifndef FGS_NAS_SECURITY_MODE_COMPLETE_H_ +#define FGS_NAS_SECURITY_MODE_COMPLETE_H_ + +/* + * Message name: security mode complete + * Description: This message is sent by the UE to the AMF in response to a SECURITY MODE COMMAND message. See table 8.2.26.1.1. + * Significance: dual + * Direction: UE to AMF + */ + +typedef struct fgs_security_mode_complete_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + FGSMobileIdentity fgsmobileidentity; + FGCNasMessageContainer fgsnasmessagecontainer; +} fgs_security_mode_complete_msg; + +int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_NAS_SECURITY_MODE_COMPLETE_H_) */ + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.c b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.c new file mode 100644 index 0000000000..d94df434b2 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.c @@ -0,0 +1,150 @@ +/* + * 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 FGSUplinkNasTransport.c + +\brief uplink nas transport procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include +#include + +#include "FGSUplinkNasTransport.h" +#include "TLVEncoder.h" + +int encode_fgs_payload_container(FGSPayloadContainer *paycontainer, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + uint32_t encoded = 0; + int encode_result; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + encoded += 2; + + if ((encode_result = encode_octet_string(&paycontainer->payloadcontainercontents, buffer + encoded, len - encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + if(iei > 0){ + *(uint16_t*) (buffer+1) = htons(encoded - 3); + } else { + *(uint16_t*) (buffer) = htons(encoded - 2); + } + + return encoded; +} + +int encode_nssai(OctetString *nssai, uint8_t iei, uint8_t *buffer) +{ + uint32_t encoded = 0; + int encode_result; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + *(buffer + encoded) = nssai->length; + encoded++; + + + if ((encode_result = encode_octet_string(nssai, buffer + encoded, nssai->length)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + return encoded; +} + +int encode_dnn(OctetString *dnn, uint8_t iei, uint8_t *buffer) +{ + uint32_t encoded = 0; + int encode_result; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + *(buffer + encoded) = dnn->length; + encoded++; + + if ((encode_result = encode_octet_string(dnn, buffer + encoded, dnn->length)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + return encoded; +} + +int encode_fgs_uplink_nas_transport(fgs_uplink_nas_transport_msg *fgs_up_nas_transport, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + *(buffer + encoded) = (fgs_up_nas_transport->payloadcontainertype.iei << 4) | (fgs_up_nas_transport->payloadcontainertype.type &0xf); + encoded++; + + if ((encode_result = encode_fgs_payload_container(&fgs_up_nas_transport->fgspayloadcontainer, + 0, buffer +encoded, len - encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + *(buffer + encoded) = 0x12; + encoded++; + + IES_ENCODE_U8(buffer, encoded, fgs_up_nas_transport->pdusessionid); + + // set request type + *(buffer + encoded) = (0x8<<4)|(fgs_up_nas_transport->requesttype &0x7); + encoded++; + + if ((encode_result = encode_nssai(&fgs_up_nas_transport->snssai, 0x22, buffer +encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + if ((encode_result = encode_dnn(&fgs_up_nas_transport->dnn, 0x25, buffer +encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + return encoded; +} + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h new file mode 100644 index 0000000000..5fabcea173 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h @@ -0,0 +1,77 @@ +/* + * 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 FGSUplinkNasTransport.h + +\brief uplink nas transport procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "MessageType.h" + +#ifndef FGS_UPLINK_NAS_TRANSPORT_H_ +#define FGS_UPLINK_NAS_TRANSPORT_H_ + +/* + * Message name: uplink nas transpaort + * Description: The UL NAS TRANSPORT message transports message payload and associated information to the AMF. See table 8.2.10.1.1. + * Significance: dual + * Direction: UE to network + */ + +typedef struct PayloadContainerType_tag{ + uint8_t iei:4; + uint8_t type:4; +}PayloadContainerType; +typedef struct FGSPayloadContainer_tag { + OctetString payloadcontainercontents; +} FGSPayloadContainer; + +typedef struct fgs_uplink_nas_transport_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + PayloadContainerType payloadcontainertype; + FGSPayloadContainer fgspayloadcontainer; + /* Optional fields */ + uint16_t pdusessionid; + uint8_t requesttype; + OctetString snssai; + OctetString dnn; +} fgs_uplink_nas_transport_msg; + +int encode_fgs_uplink_nas_transport(fgs_uplink_nas_transport_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_UPLINK_NAS_TRANSPORT_H_) */ + + diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c new file mode 100644 index 0000000000..d8fde7e2cc --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c @@ -0,0 +1,70 @@ +/* + * 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 RegistrationAccept.c + +\brief 5GS registration accept procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "RegistrationAccept.h" +#include "assertions.h" + +int decode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len) +{ + uint32_t decoded = 0; + int decoded_result = 0; + + /* Decoding mandatory fields */ + if ((decoded_result = decode_fgs_registration_result(®istration_accept->fgsregistrationresult, 0, *(buffer + decoded), len - decoded)) < 0) + return decoded_result; + + decoded += decoded_result; + + // todo ,Decoding optional fields + return decoded; +} + +int encode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + + LOG_FUNC_IN; + + + *(buffer + encoded) = encode_fgs_registration_result(®istration_accept->fgsregistrationresult); + encoded = encoded + 2; + + // todo ,Encoding optional fields + LOG_FUNC_RETURN(encoded); +} + diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h new file mode 100644 index 0000000000..08daec2646 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h @@ -0,0 +1,66 @@ +/* + * 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 RegistrationAccept.h + +\brief 5GS registration accept procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "MessageType.h" +#include "FGSRegistrationResult.h" + +#ifndef REGISTRATION_ACCEPT_H_ +#define REGISTRATION_ACCEPT_H_ + +/* + * Message name: Registration accept + * Description: The REGISTRATION ACCEPT message is sent by the AMF to the UE. See table 8.2.7.1.1. + * Significance: dual + * Direction: network to UE + */ + +typedef struct registration_accept_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + FGSRegistrationResult fgsregistrationresult; +} registration_accept_msg; + +int decode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len); + +int encode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(REGISTRATION_ACCEPT_H_) */ + diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.c b/openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.c new file mode 100644 index 0000000000..668e665351 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.c @@ -0,0 +1,61 @@ +/* + * 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 +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "RegistrationComplete.h" +#include "SORTransparentContainer.h" + +int decode_registration_complete(registration_complete_msg *registration_complete, uint8_t *buffer, uint32_t len) +{ + uint32_t decoded = 0; + int decoded_result = 0; + + /* Decoding mandatory fields */ + if ((decoded_result = decode_sor_transparent_container(®istration_complete->sortransparentcontainer, 0, buffer + decoded, len - decoded)) < 0) + return decoded_result; + else + decoded += decoded_result; + + return decoded; +} + +int encode_registration_complete(registration_complete_msg *registration_complete, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + if ((encode_result = + encode_sor_transparent_container(®istration_complete->sortransparentcontainer, 0, + buffer + encoded, len - encoded)) < 0) //Return in case of error + return encode_result; + else + encoded += encode_result; + + return encoded; +} + diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.h b/openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.h new file mode 100644 index 0000000000..0fbf2abde1 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationComplete.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 RegistrationRequest.h + +\brief registration request procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "MessageType.h" +#include "SORTransparentContainer.h" + +#ifndef REGISTRATION_COMPLETE_H_ +#define REGISTRATION_COMPLETE_H_ + + +typedef struct registration_complete_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + + /* Optional fields */ + SORTransparentContainer sortransparentcontainer; +} registration_complete_msg; + + +int decode_registration_complete(registration_complete_msg *registrationcomplete, uint8_t *buffer, uint32_t len); + +int encode_registration_complete(registration_complete_msg *registrationcomplete, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(REGISTRATION_COMPLETE_H_) */ + diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c new file mode 100644 index 0000000000..3d177c396a --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c @@ -0,0 +1,114 @@ +/* + * 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 RegistrationRequest.c + * \brief registration request procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + +#include +#include +#include +#include + +#include "nas_log.h" + +#include "RegistrationRequest.h" + +int decode_registration_request(registration_request_msg *registration_request, uint8_t *buffer, uint32_t len) +{ + uint32_t decoded = 0; + int decoded_result = 0; + + LOG_FUNC_IN; + LOG_TRACE(INFO, "EMM - registration_request len = %d", + len); + + /* Decoding mandatory fields */ + if ((decoded_result = decode_5gs_registration_type(®istration_request->fgsregistrationtype, 0, *(buffer + decoded) & 0x0f, len - decoded)) < 0) { + // return decoded_result; + LOG_FUNC_RETURN(decoded_result); + } + + if ((decoded_result = decode_u8_nas_key_set_identifier(®istration_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) { + // return decoded_result; + LOG_FUNC_RETURN(decoded_result); + } + + decoded++; + + if ((decoded_result = decode_5gs_mobile_identity(®istration_request->fgsmobileidentity, 0, buffer + decoded, len - decoded)) < 0) { + // return decoded_result; + LOG_FUNC_RETURN(decoded_result); + } else + decoded += decoded_result; + + + // TODO, Decoding optional fields + + return decoded; +} + +int encode_registration_request(registration_request_msg *registration_request, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + *(buffer + encoded) = ((encode_u8_nas_key_set_identifier(®istration_request->naskeysetidentifier) & 0x0f) << 4) | (encode_5gs_registration_type(®istration_request->fgsregistrationtype) & 0x0f); + encoded++; + + if ((encode_result = + encode_5gs_mobile_identity(®istration_request->fgsmobileidentity, 0, buffer + + encoded, len - encoded)) < 0) //Return in case of error + return encode_result; + else + encoded += encode_result; + + if ((registration_request->presencemask & REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT) + == REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT) { + if ((encode_result = encode_5gmm_capability(®istration_request->fgmmcapability, + REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI, buffer + encoded, len - + encoded)) < 0) + // Return in case of error + return encode_result; + else + encoded += encode_result; + } + + if ((registration_request->presencemask & REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT) + == REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT) { + if ((encode_result = encode_nrue_security_capability(®istration_request->nruesecuritycapability, + REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI, buffer + encoded, len - + encoded)) < 0) + // Return in case of error + return encode_result; + else + encoded += encode_result; + } + + + // TODO, Encoding optional fields + return encoded; +} + diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h new file mode 100644 index 0000000000..ce534bfff9 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.h @@ -0,0 +1,125 @@ +/* + * 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 RegistrationRequest.h + * \brief registration request procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "FGSMobileIdentity.h" +#include "NasKeySetIdentifier.h" +#include "FGSRegistrationType.h" +#include "MessageType.h" +#include "FGMMCapability.h" +#include "NrUESecurityCapability.h" + +#ifndef REGISTRATION_REQUEST_H_ +#define REGISTRATION_REQUEST_H_ + + +# define REGISTRATION_REQUEST_NON_CURRENT_NATIVE_NAS_KEYSET_PRESENT (1<<0) +# define REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT (1<<1) +# define REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT (1<<2) +# define REGISTRATION_REQUEST_REQUESTED_NSSAI_PRESENT (1<<3) +# define REGISTRATION_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT (1<<4) +# define REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_PRESENT (1<<5) +# define REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT (1<<6) +# define REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT (1<<7) +# define REGISTRATION_REQUEST_MICO_INDICATION_PRESENT (1<<8) +# define REGISTRATION_REQUEST_UE_STATUS_PRESENT (1<<9) +# define REGISTRATION_REQUEST_ADDITIONAL_GUTI_PRESENT (1<<10) +# define REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT (1<<11) +# define REGISTRATION_REQUEST_UE_USAGE_SETTING_PRESENT (1<<12) +# define REGISTRATION_REQUEST_REQUESTED_DRX_PARAMETERS_PRESENT (1<<13) +# define REGISTRATION_REQUEST_EPS_NAS_MESSAGE_CONTAINER_PRESENT (1<<14) +# define REGISTRATION_REQUEST_LADN_INDICATION_PRESENT (1<<15) +# define REGISTRATION_REQUEST_PAYLOAD_CONTAINER_TYPE_PRESENT (1<<16) +# define REGISTRATION_REQUEST_PAYLOAD_CONTAINER_PRESENT (1<<17) +# define REGISTRATION_REQUEST_NETWORK_SLICING_INDICATION_PRESENT (1<<18) +# define REGISTRATION_REQUEST_5GS_UPDATE_TYPE_PRESENT (1<<19) +# define REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT (1<<20) +# define REGISTRATION_REQUEST_EPS_BEARER_CONTEXT_STATUS_PRESENT (1<<21) + +typedef enum registration_request_iei_tag { + REGISTRATION_REQUEST_NON_CURRENT_NATIVE_NAS_KEYSET_IEI = 0xC0, /* 0xC- = 192- */ + REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI = 0x10, /* 0x10 = 16 */ + REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI = 0x2E, /* 0x2E = 46 */ + REGISTRATION_REQUEST_REQUESTED_NSSAI_IEI = 0x2F, /* 0x2F = 47 */ + REGISTRATION_REQUEST_LAST_VISITED_REGISTERED_TAI_IEI = 0x52, /* 0x52 = 82 */ + REGISTRATION_REQUEST_S1_UE_NETWORK_CAPABILITY_IEI = 0x17, /* 0x17 = 23 */ + REGISTRATION_REQUEST_UPLINK_DATA_STATUS_IEI = 0x40, /* 0x40 = 64 */ + REGISTRATION_REQUEST_PDU_SESSION_STATUS_IEI = 0x50, /* 0x50 = 80 */ + REGISTRATION_REQUEST_MICO_INDICATION_IEI = 0xB0, /* 0xB- = 176- */ + REGISTRATION_REQUEST_UE_STATUS_IEI = 0x2B, /* 0x2B = 43 */ + REGISTRATION_REQUEST_ADDITIONAL_GUTI_IEI = 0x77, /* 0x77 = 119 */ + REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_IEI = 0x25, /* 0x25 = 37 */ + REGISTRATION_REQUEST_UE_USAGE_SETTING_IEI = 0x18, /* 0x18 = 24 */ + REGISTRATION_REQUEST_REQUESTED_DRX_PARAMETERS_IEI = 0x51, /* 0x51 = 81 */ + REGISTRATION_REQUEST_EPS_NAS_MESSAGE_CONTAINER_IEI = 0x70, /* 0x70 = 112 */ + REGISTRATION_REQUEST_LADN_INDICATION_IEI = 0x74, /* 0x74 = 116 */ + REGISTRATION_REQUEST_PAYLOAD_CONTAINER_TYPE_IEI = 0x80, /* 0x80 = 128 */ + REGISTRATION_REQUEST_PAYLOAD_CONTAINER_IEI = 0x7B, /* 0x7B = 123 */ + REGISTRATION_REQUEST_NETWORK_SLICING_INDICATION_IEI = 0x90, /* 0x90 = 144 */ + REGISTRATION_REQUEST_5GS_UPDATE_TYPE_IEI = 0x53, /* 0x53 = 83 */ + REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_IEI = 0x71, /* 0x71 = 113 */ + REGISTRATION_REQUEST_EPS_BEARER_CONTEXT_STATUS_IEI = 0x60 /* 0x60 = 96 */ +} registration_request_iei; + +/* + * Message name: Registration request + * Description: This message is sent by the UE to the AMF. See TS24.501 table 8.2.6.1.1. + * Significance: dual + * Direction: UE to network + */ + +typedef struct registration_request_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + FGSRegistrationType fgsregistrationtype; + NasKeySetIdentifier naskeysetidentifier; + FGSMobileIdentity fgsmobileidentity; + + /* Optional fields */ + uint32_t presencemask; + FGMMCapability fgmmcapability; + NrUESecurityCapability nruesecuritycapability; +} registration_request_msg; + +int decode_registration_request(registration_request_msg *registrationrequest, uint8_t *buffer, uint32_t len); + +int encode_registration_request(registration_request_msg *registrationrequest, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(REGISTRATION_REQUEST_H_) */ + diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c new file mode 100644 index 0000000000..bc4d34d650 --- /dev/null +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c @@ -0,0 +1,61 @@ +/* + * 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 PduSessionEstablishRequest.c + +\brief pdu session establishment request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "PduSessionEstablishRequest.h" + + +int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer) +{ + int encoded = 0; + + + *(buffer + encoded) = pdusessionestablishrequest->protocoldiscriminator; + encoded++; + *(buffer + encoded) = pdusessionestablishrequest->pdusessionid; + encoded++; + *(buffer + encoded) = pdusessionestablishrequest->pti; + encoded++; + *(buffer + encoded) = pdusessionestablishrequest->pdusessionestblishmsgtype; + encoded++; + + IES_ENCODE_U16(buffer, encoded, pdusessionestablishrequest->maxdatarate); + + return encoded; +} + + diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h new file mode 100644 index 0000000000..ac5b250f66 --- /dev/null +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PduSessionEstablishRequest.h + +\brief pdu session establishment request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "MessageType.h" + +#ifndef PDU_SESSION_ESTABLISHMENT_REQUEST_H_ +#define PDU_SESSION_ESTABLISHMENT_REQUEST_H_ + + +/* + * Message name: pdu session establishment request + * Description: The PDU SESSION ESTABLISHMENT REQUEST message is sent by the UE to the SMF to initiate establishment of a PDU session. See table 8.3.1.1.1. + * Significance: dual + * Direction: UE to network + */ + +typedef struct pdu_session_establishment_request_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + uint8_t pdusessionid; + uint8_t pti; + MessageType pdusessionestblishmsgtype; + uint16_t maxdatarate; + /* Optional fields */ +} pdu_session_establishment_request_msg; + + +int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer); + +#endif /* ! defined(PDU_SESSION_ESTABLISHMENT_REQUEST_H_) */ + + diff --git a/common/utils/itti_analyzer/libparser/xml_parse.h b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c similarity index 60% rename from common/utils/itti_analyzer/libparser/xml_parse.h rename to openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c index f9624bc06b..e3b4bd021a 100644 --- a/common/utils/itti_analyzer/libparser/xml_parse.h +++ b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.c @@ -19,25 +19,32 @@ * contact@openairinterface.org */ -#include "rc.h" -#include "types.h" -#ifndef XML_PARSE_H_ -#define XML_PARSE_H_ +/*! \file ExtendedProtocolDiscriminator.c -extern void *xml_raw_data; -extern uint32_t xml_raw_data_size; +\brief Extended protocol discriminator for registration request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ -extern types_t *root; +#include +#include +#include -int xml_parse_file(const char *filename); -int xml_parse_buffer(char *xml_buffer, const int size); +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "ExtendedProtocolDiscriminator.h" -int dissect_signal(buffer_t *buffer, ui_set_signal_text_cb_t ui_set_signal_text_cb, - gpointer user_data); +int encode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + return 0; +} -int dissect_signal_header(buffer_t *buffer, ui_set_signal_text_cb_t ui_set_signal_text_cb, - gpointer cb_user_data); +int decode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + return 0; +} -#endif /* XML_PARSE_H_ */ diff --git a/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h new file mode 100644 index 0000000000..3bf1f6ec8f --- /dev/null +++ b/openair3/NAS/COMMON/IES/ExtendedProtocolDiscriminator.h @@ -0,0 +1,48 @@ +/* + * 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 ExtendedProtocolDiscriminator.h + +\brief Extended protocol discriminator for registration request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "OctetString.h" + +#ifndef EXTENDED_PROTOCOL_DISCRIMINATOR_H_ +#define EXTENDED_PROTOCOL_DISCRIMINATOR_H_ + +typedef uint8_t ExtendedProtocolDiscriminator; + +int encode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len); + +int decode_ex_protocol_discriminator(ExtendedProtocolDiscriminator *exprotocoldiscriminator, uint8_t iei, uint8_t *buffer, uint32_t len); + +#endif /* EXTENDED PROTOCOL DISCRIMINATOR_H_ */ + diff --git a/openair3/NAS/COMMON/IES/FGCNasMessageContainer.c b/openair3/NAS/COMMON/IES/FGCNasMessageContainer.c new file mode 100644 index 0000000000..874f61e7b3 --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGCNasMessageContainer.c @@ -0,0 +1,98 @@ +/* + * 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 FGCNasMessageContainer.c + +\brief security mode complete procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "FGCNasMessageContainer.h" + +int decode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + int decoded = 0; + uint8_t ielen = 0; + int decode_result; + + if (iei > 0) { + CHECK_IEI_DECODER(iei, *buffer); + decoded++; + } + + ielen = *(buffer + decoded); + decoded += 2; + CHECK_LENGTH_DECODER(len - decoded, ielen); + + if ((decode_result = decode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0) + return decode_result; + else + decoded += decode_result; + + return decoded; +} +int encode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + uint32_t encoded = 0; + int encode_result; + /* Checking IEI and pointer */ + CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, FGC_NAS_MESSAGE_CONTAINER_MINIMUM_LENGTH, len); + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + encoded += 2; + + if ((encode_result = encode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, buffer + encoded, len - encoded)) < 0) { + return encode_result; + } else { + *(uint16_t*) (buffer+1) = htons(encoded + encode_result - 3); + encoded += encode_result; + } + + return encoded; +} + +void dump_fgc_nas_message_container_xml(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei) +{ + printf("\n"); + + if (iei > 0) + /* Don't display IEI if = 0 */ + printf(" 0x%X\n", iei); + + printf("%s", dump_octet_string_xml(&nasmessagecontainer->nasmessagecontainercontents)); + printf("\n"); +} + + diff --git a/openair3/NAS/COMMON/IES/FGCNasMessageContainer.h b/openair3/NAS/COMMON/IES/FGCNasMessageContainer.h new file mode 100644 index 0000000000..19a1679b7e --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGCNasMessageContainer.h @@ -0,0 +1,54 @@ +/* + * 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 FGCNasMessageContainer.h + +\brief security mode complete procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "OctetString.h" + +#ifndef FGC_NAS_MESSAGE_CONTAINER_H_ +#define FGC_NAS_MESSAGE_CONTAINER_H_ + +#define FGC_NAS_MESSAGE_CONTAINER_MINIMUM_LENGTH 4 +#define FGC_NAS_MESSAGE_CONTAINER_MAXIMUM_LENGTH 65535 + +typedef struct FGCNasMessageContainer_tag { + OctetString nasmessagecontainercontents; +} FGCNasMessageContainer; + +int encode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len); + +int decode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len); + +void dump_fgc_nas_message_container_xml(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei); + +#endif /* FGC NAS MESSAGE CONTAINER_H_ */ + diff --git a/openair3/NAS/COMMON/IES/FGMMCapability.c b/openair3/NAS/COMMON/IES/FGMMCapability.c new file mode 100644 index 0000000000..ce156e63bf --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGMMCapability.c @@ -0,0 +1,54 @@ +/* + * 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 FGMMCapability.c + * \brief 5GS Mobile Identity for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "FGMMCapability.h" + + + +int encode_5gmm_capability(FGMMCapability *fgmmcapability, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + if(iei){ + *buffer = fgmmcapability->iei; + encoded++; + *(buffer+encoded) = fgmmcapability->length; + encoded++; + *(buffer+encoded) = fgmmcapability->value; + encoded++; + } + return encoded; +} + diff --git a/openair2/LAYER2/NR_MAC_UE/mac.h b/openair3/NAS/COMMON/IES/FGMMCapability.h similarity index 67% rename from openair2/LAYER2/NR_MAC_UE/mac.h rename to openair3/NAS/COMMON/IES/FGMMCapability.h index 9418511adf..d427896338 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac.h +++ b/openair3/NAS/COMMON/IES/FGMMCapability.h @@ -19,30 +19,33 @@ * contact@openairinterface.org */ -/* \file mac.h - * \brief MAC data structures, constant, and function prototype - * \author R. Knopp, K.H. HSU - * \date 2018 +/*! \file FGMMCapability.h + * \brief 5GS Mobile Capability for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 * \version 0.1 - * \company Eurecom / NTUST - * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr - * \note - * \warning */ -#ifndef __LAYER2_NR_UE_MAC_DEFS_H__ -#define __LAYER2_NR_UE_MAC_DEFS_H__ #include #include -#include +#include -/*!\brief UE layer 2 status */ -typedef enum { - UE_CONNECTION_OK = 0, - UE_CONNECTION_LOST, - UE_PHY_RESYNCH, - UE_PHY_HO_PRACH -} NR_UE_L2_STATE_t; +#include "OctetString.h" + +#ifndef FGMM_CAPABILITY_H_ +#define FGMM_CAPABILITY_H_ + + +typedef struct { + uint8_t iei; + uint8_t length; + uint8_t value; +} FGMMCapability; + + +int encode_5gmm_capability(FGMMCapability *fgmmcapability, uint8_t iei, uint8_t *buffer, uint32_t len); + +#endif /* FGMM_CAPABILITY_H_ */ -#endif /*__LAYER2_NR_UE_MAC_DEFS_H__ */ diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c new file mode 100644 index 0000000000..e3204b4c0c --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -0,0 +1,239 @@ +/* + * 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 FGSMobileIdentity.c + * \brief 5GS Mobile Identity for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "FGSMobileIdentity.h" + +static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); + +static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); +static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer); +static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer); + +int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + int decoded_rc = TLV_DECODE_VALUE_DOESNT_MATCH; + int decoded = 0; + uint8_t ielen = 0; + + if (iei > 0) { + CHECK_IEI_DECODER(iei, *buffer); + decoded++; + } + + ielen = *(buffer + decoded); + decoded++; + CHECK_LENGTH_DECODER(len - decoded, ielen); + + uint8_t typeofidentity = *(buffer + decoded) & 0x7; + + if (typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI) { + decoded_rc = decode_guti_5gs_mobile_identity(&fgsmobileidentity->guti, + buffer + decoded); + } + + if (decoded_rc < 0) { + return decoded_rc; + } + + return (decoded + decoded_rc); +} + +int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + int encoded_rc = TLV_ENCODE_VALUE_DOESNT_MATCH; + uint32_t encoded = 0; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + encoded = encoded + 2; + + if (fgsmobileidentity->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI) { + encoded_rc = encode_guti_5gs_mobile_identity(&fgsmobileidentity->guti, + buffer + encoded); + } + + if (fgsmobileidentity->suci.typeofidentity == FGS_MOBILE_IDENTITY_SUCI) { + encoded_rc = encode_suci_5gs_mobile_identity(&fgsmobileidentity->suci, + buffer + encoded); + } + + if (fgsmobileidentity->imeisv.typeofidentity == FGS_MOBILE_IDENTITY_IMEISV) { + encoded_rc = encode_imeisv_5gs_mobile_identity(&fgsmobileidentity->imeisv, + buffer + encoded); + } + + if (encoded_rc < 0) { + return encoded_rc; + } + + if(iei > 0){ + *(uint16_t*) (buffer+1) = htons(encoded + encoded_rc - 3); + } else { + *(uint16_t*) buffer = htons(encoded + encoded_rc - 2); + } + + return (encoded + encoded_rc); +} + +static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer) +{ + int decoded = 0; + uint16_t temp; + guti->spare = (*(buffer + decoded) >> 4) & 0xf; + + /* + * For the 5G-GUTI, bits 5 to 8 of octet 3 are coded as "1111" + */ + if (guti->spare != 0xf) { + return (TLV_ENCODE_VALUE_DOESNT_MATCH); + } + + + guti->oddeven = (*(buffer + decoded) >> 3) & 0x1; + + /* + * For the 5G-GUTI, bits 4 of octet 3 are coded as "0" + */ + if (guti->oddeven != 0) { + return (TLV_ENCODE_VALUE_DOESNT_MATCH); + } + guti->typeofidentity = *(buffer + decoded) & 0x7; + + if (guti->typeofidentity != FGS_MOBILE_IDENTITY_5G_GUTI) { + return (TLV_ENCODE_VALUE_DOESNT_MATCH); + } + + decoded++; + guti->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf; + guti->mccdigit1 = *(buffer + decoded) & 0xf; + decoded++; + guti->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf; + guti->mccdigit3 = *(buffer + decoded) & 0xf; + decoded++; + guti->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf; + guti->mncdigit1 = *(buffer + decoded) & 0xf; + decoded++; + + + guti->amfregionid = *(buffer+decoded); + decoded++; + IES_DECODE_U16(buffer, decoded, temp); + guti->amfsetid = temp>>3; + guti->amfpointer = temp&0x3f; + + IES_DECODE_U32(buffer, decoded, guti->tmsi); + return decoded; +} + + +static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer) +{ + uint32_t encoded = 0; + uint16_t temp; + *(buffer + encoded) = 0xf0 | ((guti->oddeven & 0x1) << 3) | + (guti->typeofidentity & 0x7); + encoded++; + *(buffer + encoded) = 0x00 | ((guti->mccdigit2 & 0xf) << 4) | + (guti->mccdigit1 & 0xf); + encoded++; + *(buffer + encoded) = 0x00 | ((guti->mncdigit3 & 0xf) << 4) | + (guti->mccdigit3 & 0xf); + encoded++; + *(buffer + encoded) = 0x00 | ((guti->mncdigit2 & 0xf) << 4) | + (guti->mncdigit1 & 0xf); + encoded++; + + *(buffer + encoded) = guti->amfregionid; + encoded++; + + temp = 0x00 | ((guti->amfsetid) << 6) | (guti->amfpointer & 0x3f); + + IES_ENCODE_U16(buffer, encoded, temp); + IES_ENCODE_U32(buffer, encoded, guti->tmsi); + return encoded; +} + + +static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer) +{ + uint32_t encoded = 0; + *(buffer + encoded) = 0x00 | (suci->supiformat << 4) | (suci->typeofidentity); + encoded++; + *(buffer + encoded) = 0x00 | ((suci->mccdigit2 & 0xf) << 4) | + (suci->mccdigit1 & 0xf); + encoded++; + *(buffer + encoded) = 0x00 | ((suci->mncdigit3 & 0xf) << 4) | + (suci->mccdigit3 & 0xf); + encoded++; + *(buffer + encoded) = 0x00 | ((suci->mncdigit2 & 0xf) << 4) | + (suci->mncdigit1 & 0xf); + encoded++; + + *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit2 & 0xf) << 4) | + (suci->routingindicatordigit1 & 0xf); + encoded++; + + *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit4 & 0xf) << 4) | + (suci->routingindicatordigit3 & 0xf); + encoded++; + + *(buffer + encoded) = 0x00 | (suci->protectionschemeId & 0xf); + encoded++; + + *(buffer + encoded) = suci->homenetworkpki; + encoded++; + + IES_ENCODE_U32(buffer, encoded, suci->schemeoutput); + + return encoded; +} + +static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer) +{ + uint32_t encoded = 0; + *(buffer + encoded) = 0x00 | (imeisv->digit1 << 4) | (imeisv->oddeven << 3) | (imeisv->typeofidentity); + encoded++; + + *(buffer + encoded) = 0x00 | (imeisv->digitp1 << 4) | (imeisv->digitp); + encoded++; + + return encoded; +} + diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h new file mode 100644 index 0000000000..a673a86dd1 --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h @@ -0,0 +1,135 @@ +/* + * 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 FGSMobileIdentity.h + * \brief 5GS Mobile Identity for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + +#include +#include +#include + +#include "OctetString.h" + +#ifndef FGS_MOBILE_IDENTITY_H_ +#define FGS_MOBILE_IDENTITY_H_ + + +typedef struct { + uint8_t spare:5; + uint8_t typeofidentity:3; +} NoIdentity5GSMobileIdentity_t; + +typedef struct { + uint8_t spare1:1; + uint8_t supiformat:3; + uint8_t spare2:1; + uint8_t typeofidentity:3; + uint8_t mccdigit2:4; + uint8_t mccdigit1:4; + uint8_t mncdigit3:4; + uint8_t mccdigit3:4; + uint8_t mncdigit2:4; + uint8_t mncdigit1:4; + uint8_t routingindicatordigit2:4; + uint8_t routingindicatordigit1:4; + uint8_t routingindicatordigit4:4; + uint8_t routingindicatordigit3:4; + uint8_t spare3:1; + uint8_t spare4:1; + uint8_t spare5:1; + uint8_t spare6:1; + uint8_t protectionschemeId:4; + uint8_t homenetworkpki; + uint32_t schemeoutput; +} Suci5GSMobileIdentity_t; + +typedef struct { + uint8_t spare:4; + uint8_t oddeven:1; + uint8_t typeofidentity:3; + uint8_t mccdigit2:4; + uint8_t mccdigit1:4; + uint8_t mncdigit3:4; + uint8_t mccdigit3:4; + uint8_t mncdigit2:4; + uint8_t mncdigit1:4; + uint8_t amfregionid; + uint16_t amfsetid:10; + uint16_t amfpointer:6; + uint32_t tmsi; +} Guti5GSMobileIdentity_t; + + +typedef struct { + uint8_t digit1:4; + uint8_t oddeven:1; + uint8_t typeofidentity:3; + uint8_t digitp1:4; + uint8_t digitp:4; +} Imei5GSMobileIdentity_t; + +typedef Imei5GSMobileIdentity_t Imeisv5GSMobileIdentity_t; + + +typedef struct { + uint8_t digit1:4; + uint8_t spare:1; + uint8_t typeofidentity:3; + uint16_t amfsetid:10; + uint16_t amfpointer:6; + uint32_t tmsi; +} Stmsi5GSMobileIdentity_t; + +typedef struct { + uint8_t spare:5; + uint8_t typeofidentity:3; + uint8_t macaddr; +} Macaddr5GSMobileIdentity_t; + +typedef union FGSMobileIdentity_tag { +#define FGS_MOBILE_IDENTITY_NOIDENTITY 0b000 +#define FGS_MOBILE_IDENTITY_SUCI 0b001 +#define FGS_MOBILE_IDENTITY_5G_GUTI 0b010 +#define FGS_MOBILE_IDENTITY_IMEI 0b011 +#define FGS_MOBILE_IDENTITY_5GS_TMSI 0b100 +#define FGS_MOBILE_IDENTITY_IMEISV 0b101 +#define FGS_MOBILE_IDENTITY_MAC_ADDR 0b110 + NoIdentity5GSMobileIdentity_t noidentity; + Suci5GSMobileIdentity_t suci; + Guti5GSMobileIdentity_t guti; + Imei5GSMobileIdentity_t imei; + Stmsi5GSMobileIdentity_t stmsi; + Imeisv5GSMobileIdentity_t imeisv; + Macaddr5GSMobileIdentity_t macaddress; +} FGSMobileIdentity; + +int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len); + +int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len); + +#endif /* FGS MOBILE IDENTITY_H_ */ + diff --git a/openair3/NAS/COMMON/IES/FGSRegistrationResult.c b/openair3/NAS/COMMON/IES/FGSRegistrationResult.c new file mode 100644 index 0000000000..e580b14409 --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGSRegistrationResult.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 FGSRegistrationResult.c + +\brief 5GS Registration result for registration request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "FGSRegistrationResult.h" + + +int decode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult, uint8_t iei, uint16_t value, uint32_t len) +{ + int decoded = 0; + uint16_t *buffer = &value; + fgsregistrationresult->registrationresult = *buffer & 0x7; + fgsregistrationresult->smsallowed = *buffer & 0x8; + decoded = decoded+2; + return decoded; +} + +uint16_t encode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult) +{ + uint16_t bufferReturn; + uint16_t *buffer = &bufferReturn; + uint8_t encoded = 0; + *(buffer + encoded) = 0x00 | (fgsregistrationresult->smsallowed & 0x8) | + (fgsregistrationresult->registrationresult & 0x7); + encoded= encoded+2; + + return bufferReturn; +} + diff --git a/openair3/NAS/COMMON/IES/FGSRegistrationResult.h b/openair3/NAS/COMMON/IES/FGSRegistrationResult.h new file mode 100644 index 0000000000..0a2dedc2e5 --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGSRegistrationResult.h @@ -0,0 +1,59 @@ +/* + * 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 FGSRegistrationResult.h + +\brief 5GS Registration result for registration request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "OctetString.h" + + + +#ifndef FGS_REGISTRATION_RESULT_H_ +#define FGS_REGISTRATION_RESULT_H_ +#define FGS_REGISTRATION_RESULT_3GPP 0b001 +#define FGS_REGISTRATION_RESULT_NON_3GPP 0b010 +#define FGS_REGISTRATION_RESULT_3GPP_AND_NON_3GPP 0b011 + +typedef struct { + uint8_t iei; + uint8_t resultlength; + uint8_t spare:4; + uint8_t smsallowed:1; + uint8_t registrationresult:3; +} FGSRegistrationResult; + + +uint16_t encode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult); + +int decode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult, uint8_t iei, uint16_t value, uint32_t len); + +#endif /* FGS REGISTRATION RESULT_H_*/ + diff --git a/openair3/NAS/COMMON/IES/FGSRegistrationType.c b/openair3/NAS/COMMON/IES/FGSRegistrationType.c new file mode 100644 index 0000000000..7f1c3ae667 --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGSRegistrationType.c @@ -0,0 +1,65 @@ +/* + * 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 FGSRegistrationType.c + * \brief 5GS Registration Type for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "FGSRegistrationType.h" + +int decode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype, uint8_t iei, uint8_t value, uint32_t len) +{ + int decoded = 0; + uint8_t *buffer = &value; + if (iei > 0) { + CHECK_IEI_DECODER((*buffer & 0xf0), iei); + } + + *fgsregistrationtype = *buffer & 0x7; + decoded++; + + return decoded; +} + +int encode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype) +{ + uint8_t bufferReturn; + uint8_t *buffer = &bufferReturn; + uint8_t encoded = 0; + uint8_t iei = 0; + *(buffer + encoded) = 0x00 | (iei & 0xf0) | 0x8| + (*fgsregistrationtype & 0x7); + encoded++; + + return bufferReturn; +} + diff --git a/openair3/NAS/COMMON/IES/FGSRegistrationType.h b/openair3/NAS/COMMON/IES/FGSRegistrationType.h new file mode 100644 index 0000000000..a548d45d93 --- /dev/null +++ b/openair3/NAS/COMMON/IES/FGSRegistrationType.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 + */ + +/*! \file FGSRegistrationType.h + * \brief 5GS Registration Type for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ +#include +#include +#include + +#include "OctetString.h" + +#ifndef FGS_REGISTRATION_TYPE_H_ +#define FGS_REGISTRATION_TYPE_H_ + +#define FGS_REGISTRATION_TYPE_MINIMUM_LENGTH 1 +#define FGS_REGISTRATION_TYPE_MAXIMUM_LENGTH 1 + +typedef uint8_t FGSRegistrationType; + + +#define INITIAL_REGISTRATION 0b001 +#define MOBILITY_REGISTRATION_UPDATING 0b010 +#define PERIODIC_REGISTRATION_UPDATING 0b011 +#define EMERGENCY_REGISTRATION 0b100 + +int encode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype); + +int decode_5gs_registration_type(FGSRegistrationType *fgsregistrationtype, uint8_t iei, uint8_t value, uint32_t len); + + +#endif /* FGS_REGISTRATION_TYPE_H_*/ + diff --git a/openair3/NAS/COMMON/IES/NrUESecurityCapability.c b/openair3/NAS/COMMON/IES/NrUESecurityCapability.c new file mode 100644 index 0000000000..6c0ff7e7c7 --- /dev/null +++ b/openair3/NAS/COMMON/IES/NrUESecurityCapability.c @@ -0,0 +1,63 @@ +/* + * 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 NrUESecurityCapability.c + * \brief 5GS UE Security Capability for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "NrUESecurityCapability.h" + + + +int encode_nrue_security_capability(NrUESecurityCapability *nruesecuritycapability, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + if(iei){ + *buffer = nruesecuritycapability->iei; + encoded++; + *(buffer+encoded) = nruesecuritycapability->length; + encoded++; + *(buffer+encoded) = nruesecuritycapability->fg_EA; + encoded++; + *(buffer+encoded) = nruesecuritycapability->fg_IA; + encoded++; + *(buffer+encoded) = nruesecuritycapability->EEA; + encoded++; + *(buffer+encoded) = nruesecuritycapability->EIA; + encoded++; + if((nruesecuritycapability->length - 4) > 0) + encoded = encoded + nruesecuritycapability->length - 4; + } + return encoded; +} + diff --git a/common/utils/itti_analyzer/libui/ui_signal_dissect_view.h b/openair3/NAS/COMMON/IES/NrUESecurityCapability.h similarity index 60% rename from common/utils/itti_analyzer/libui/ui_signal_dissect_view.h rename to openair3/NAS/COMMON/IES/NrUESecurityCapability.h index a5ccf6a9eb..10aa0cf0ea 100644 --- a/common/utils/itti_analyzer/libui/ui_signal_dissect_view.h +++ b/openair3/NAS/COMMON/IES/NrUESecurityCapability.h @@ -19,18 +19,35 @@ * contact@openairinterface.org */ -#ifndef UI_SIGNAL_DISSECT_VIEW_H_ -#define UI_SIGNAL_DISSECT_VIEW_H_ +/*! \file NrUESecurityCapability.h + * \brief 5GS UE Security Capability for registration request procedures + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + +#include +#include +#include + +#include "OctetString.h" + +#ifndef NRUE_SECURITY_CAPABILITY_H_ +#define NRUE_SECURITY_CAPABILITY_H_ + typedef struct { - GtkWidget *text_view; - PangoFontDescription *text_view_font; -} ui_text_view_t; + uint8_t iei; + uint8_t length; + uint8_t fg_EA; + uint8_t fg_IA; + uint8_t EEA; + uint8_t EIA; +} NrUESecurityCapability; -ui_text_view_t *ui_signal_dissect_new(GtkWidget *hbox); -int ui_signal_dissect_clear_view(ui_text_view_t *text_view); +int encode_nrue_security_capability(NrUESecurityCapability *nruesecuritycapability, uint8_t iei, uint8_t *buffer, uint32_t len); -gboolean ui_signal_set_text(gpointer user_data, gchar *text, gint length); +#endif /* NRUE_SECURITY_CAPABILITY_H_ */ -#endif /*UI_SIGNAL_DISSECT_VIEW_H_ */ diff --git a/openair3/NAS/COMMON/IES/SORTransparentContainer.c b/openair3/NAS/COMMON/IES/SORTransparentContainer.c new file mode 100644 index 0000000000..3ab2a14c3d --- /dev/null +++ b/openair3/NAS/COMMON/IES/SORTransparentContainer.c @@ -0,0 +1,103 @@ +/* + * 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 +#include +#include + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "SORTransparentContainer.h" +#include "nas_log.h" + +//#define NAS_DEBUG 1 + +int decode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + int decoded = 0; + int decode_result; + uint16_t ielen; + + LOG_FUNC_IN; + + if (iei > 0) { + CHECK_IEI_DECODER(iei, *buffer); + decoded++; + } + + DECODE_LENGTH_U16(buffer + decoded, ielen, decoded); + + CHECK_LENGTH_DECODER(len - decoded, ielen); + + + if ((decode_result = decode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, ielen, buffer + decoded, len - decoded)) < 0) { + LOG_FUNC_RETURN(decode_result); + } else { + decoded += decode_result; + } + +#if defined (NAS_DEBUG) + dump_sor_transparent_container_xml(sortransparentcontainer, iei); +#endif + LOG_FUNC_RETURN(decoded); +} + +int encode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + uint8_t *lenPtr; + uint32_t encoded = 0; + int32_t encode_result; + /* Checking IEI and pointer */ + CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, SOR_TRANSPARENT_CONTAINER_MINIMUM_LENGTH, len); +#if defined (NAS_DEBUG) + dump_sor_transparent_container_xml(sortransparentcontainer, iei); +#endif + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + lenPtr = (buffer + encoded); + + //encoded += 2; + //if ((encode_result = encode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, buffer + sizeof(uint16_t), len - sizeof(uint16_t))) < 0) + if ((encode_result = encode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, lenPtr + sizeof(uint16_t), len - sizeof(uint16_t))) < 0) + return encode_result; + else + encoded += encode_result; + + ENCODE_U16(lenPtr, encode_result, encoded); + return encoded; +} + +void dump_sor_transparent_container_xml(SORTransparentContainer *sortransparentcontainer, uint8_t iei) +{ + printf("\n"); + + if (iei > 0) + /* Don't display IEI if = 0 */ + printf(" 0x%X\n", iei); + + printf("%s", dump_octet_string_xml(&sortransparentcontainer->sortransparentcontainercontents)); + printf("\n"); +} + diff --git a/common/utils/memory_pools.h b/openair3/NAS/COMMON/IES/SORTransparentContainer.h similarity index 55% rename from common/utils/memory_pools.h rename to openair3/NAS/COMMON/IES/SORTransparentContainer.h index 1c1997f7f2..587419b1f9 100644 --- a/common/utils/memory_pools.h +++ b/openair3/NAS/COMMON/IES/SORTransparentContainer.h @@ -19,24 +19,27 @@ * contact@openairinterface.org */ -#ifndef MEMORY_POOLS_H_ -#define MEMORY_POOLS_H_ - +#include +#include #include -typedef void * memory_pools_handle_t; -typedef void * memory_pool_item_handle_t; +#include "OctetString.h" -memory_pools_handle_t memory_pools_create (uint32_t pools_number); +#ifndef SOR_TRANSPARENT_CONTAINER_H_ +#define SOR_TRANSPARENT_CONTAINER_H_ -char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle); +#define SOR_TRANSPARENT_CONTAINER_MINIMUM_LENGTH 2 // [length]+[length] +#define SOR_TRANSPARENT_CONTAINER_MAXIMUM_LENGTH 65538 // [IEI]+[length]+[length]+[ESM msg] -int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size); +typedef struct SORTransparentContainer_tag { + OctetString sortransparentcontainercontents; +} SORTransparentContainer; -memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1); +int encode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len); -int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0); +int decode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len); -void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info); +void dump_sor_transparent_container_xml(SORTransparentContainer *sortransparentcontainer, uint8_t iei); + +#endif /* ESM MESSAGE CONTAINER_H_ */ -#endif /* MEMORY_POOLS_H_ */ diff --git a/common/utils/itti_analyzer/libresolver/resolvers.h b/openair3/NAS/COMMON/IES/SpareHalfOctet.c similarity index 64% rename from common/utils/itti_analyzer/libresolver/resolvers.h rename to openair3/NAS/COMMON/IES/SpareHalfOctet.c index 17e16462b4..60c45e07c2 100644 --- a/common/utils/itti_analyzer/libresolver/resolvers.h +++ b/openair3/NAS/COMMON/IES/SpareHalfOctet.c @@ -19,27 +19,32 @@ * contact@openairinterface.org */ -#ifndef RESOLVERS_H_ -#define RESOLVERS_H_ -int resolve_typedefs(types_t **head); +/*! \file SpareHalfOctet.c -int resolve_struct(types_t **head); +\brief registration request procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ -int resolve_pointer_type(types_t **head); +#include +#include +#include -int resolve_field(types_t **head); -int resolve_array(types_t **head); +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "SpareHalfOctet.h" -int resolve_reference(types_t **head); +int decode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + return 0; +} -int resolve_union(types_t **head); +int encode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + return 0; +} -int resolve_file(types_t **head); - -int resolve_function(types_t **head); - -int search_file(types_t *head, types_t **found, int id); - -#endif /* RESOLVERS_H_ */ diff --git a/common/utils/itti_analyzer/libui/ui_notifications.h b/openair3/NAS/COMMON/IES/SpareHalfOctet.h similarity index 60% rename from common/utils/itti_analyzer/libui/ui_notifications.h rename to openair3/NAS/COMMON/IES/SpareHalfOctet.h index 33ef0ff5c0..fbf410d4f8 100644 --- a/common/utils/itti_analyzer/libui/ui_notifications.h +++ b/openair3/NAS/COMMON/IES/SpareHalfOctet.h @@ -19,29 +19,33 @@ * contact@openairinterface.org */ -#ifndef UI_NOTIFICATIONS_H_ -#define UI_NOTIFICATIONS_H_ -typedef void (*message_write_callback_t) (const gpointer buffer, const gchar *signal_name); +/*! \file SpareHalfOctet.h -int ui_disable_connect_button(void); +\brief registration request procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ -int ui_enable_connect_button(void); +#include +#include +#include -int ui_messages_read(char *filename); +#include "OctetString.h" -int ui_messages_open_file_chooser(void); +#ifndef SPARE_HALF_OCTET_H_ +#define SPARE_HALF_OCTET_H_ -int ui_messages_save_file_chooser(gboolean filtered); +#define SPARE_HALF_OCTET_MINIMUM_LENGTH 1 +#define SPARE_HALF_OCTET_MAXIMUM_LENGTH 1 -int ui_filters_open_file_chooser(void); +typedef uint8_t SpareHalfOctet; -int ui_filters_save_file_chooser(void); +int encode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len); -void ui_progressbar_window_destroy(void); +int decode_spare_half_octet(SpareHalfOctet *sparehalfoctet, uint8_t iei, uint8_t *buffer, uint32_t len); -int ui_progress_bar_set_fraction(double fraction); +#endif /* SPARE HALF OCTET_H_ */ -int ui_progress_bar_terminate(void); - -#endif /* UI_NOTIFICATIONS_H_ */ diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h new file mode 100644 index 0000000000..906c0cf504 --- /dev/null +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -0,0 +1,391 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#ifndef NR_NAS_DEFS_H +#define NR_NAS_DEFS_H + +#include +#include +#include + +/* TS 24.007 possible L3 formats: + Table 11.1: Formats of information elements + Format Meaning IEI present LI present Value part present + T Type only yes no no + V Value only no no yes + TV Type and Value yes no yes + LV Length and Value no yes yes + TLV Type, Length and Value yes yes yes + LV-E Length and Value no yes yes + TLV-E Type, Length and Value yes yes yes +*/ + +/* Map task id to printable name. */ +typedef struct { + int id; + char text[256]; +} text_info_t; + +static inline const char * idToText(const text_info_t* table, int size, int id) { + for(int i=0; i TS 24.007 +typedef enum { + SGSsessionmanagementmessages=0x2e, //LTEbox: 0xC0 ??? + SGSmobilitymanagementmessages=0x7e, +} Extendedprotocoldiscriminator_t; + +#define FOREACH_TYPE(TYPE_DEF) \ + TYPE_DEF( Registrationrequest,0x41 )\ +TYPE_DEF( Registrationaccept,0x42 )\ +TYPE_DEF( Registrationcomplete,0x43 )\ +TYPE_DEF( Registrationreject,0x44 )\ +TYPE_DEF( DeregistrationrequestUEoriginating,0x45 )\ +TYPE_DEF( DeregistrationacceptUEoriginating,0x46 )\ +TYPE_DEF( DeregistrationrequestUEterminated,0x47 )\ +TYPE_DEF( DeregistrationacceptUEterminated,0x48 )\ +TYPE_DEF( Servicerequest,0x4c )\ +TYPE_DEF( Servicereject,0x4d )\ +TYPE_DEF( Serviceaccept,0x4e )\ +TYPE_DEF( Controlplaneservicerequest,0x4f )\ +TYPE_DEF( Networkslicespecificauthenticationcommand,0x50 )\ +TYPE_DEF( Networkslicespecificauthenticationcomplete,0x51 )\ +TYPE_DEF( Networkslicespecificauthenticationresult,0x52 )\ +TYPE_DEF( Configurationupdatecommand,0x54 )\ +TYPE_DEF( Configurationupdatecomplete,0x55 )\ +TYPE_DEF( Authenticationrequest,0x56 )\ +TYPE_DEF( Authenticationresponse,0x57 )\ +TYPE_DEF( Authenticationreject,0x58 )\ +TYPE_DEF( Authenticationfailure,0x59 )\ +TYPE_DEF( Authenticationresult,0x5a )\ +TYPE_DEF( Identityrequest,0x5b )\ +TYPE_DEF( Identityresponse,0x5c )\ +TYPE_DEF( Securitymodecommand,0x5d )\ +TYPE_DEF( Securitymodecomplete,0x5e )\ +TYPE_DEF( Securitymodereject,0x5f )\ +TYPE_DEF( SGMMstatus,0x64 )\ +TYPE_DEF( Notification,0x65 )\ +TYPE_DEF( Notificationresponse,0x66 )\ +TYPE_DEF( ULNAStransport,0x67 )\ +TYPE_DEF( DLNAStransport,0x68 )\ +TYPE_DEF( PDUsessionestablishmentrequest,0xc1 )\ +TYPE_DEF( PDUsessionestablishmentaccept,0xc2 )\ +TYPE_DEF( PDUsessionestablishmentreject,0xc3 )\ +TYPE_DEF( PDUsessionauthenticationcommand,0xc5 )\ +TYPE_DEF( PDUsessionauthenticationcomplete,0xc6 )\ +TYPE_DEF( PDUsessionauthenticationresult,0xc7 )\ +TYPE_DEF( PDUsessionmodificationrequest,0xc9 )\ +TYPE_DEF( PDUsessionmodificationreject,0xca )\ +TYPE_DEF( PDUsessionmodificationcommand,0xcb )\ +TYPE_DEF( PDUsessionmodificationcomplete,0xcc )\ +TYPE_DEF( PDUsessionmodificationcommandreject,0xcd )\ +TYPE_DEF( PDUsessionreleaserequest,0xd1 )\ +TYPE_DEF( PDUsessionreleasereject,0xd2 )\ +TYPE_DEF( PDUsessionreleasecommand,0xd3 )\ +TYPE_DEF( PDUsessionreleasecomplete,0xd4 )\ +TYPE_DEF( SGSMstatus,0xd6 )\ + +static const text_info_t message_text_info[] = { + FOREACH_TYPE(TO_TEXT) +}; + +//! Tasks id of each task +typedef enum { + FOREACH_TYPE(TO_ENUM) +} SGSmobilitymanagementmessages_t; + +// TS 24.501 +typedef enum { + notsecurityprotected=0, + Integrityprotected=1, + Integrityprotectedandciphered=2, + Integrityprotectedwithnew5GNASsecuritycontext=3, + Integrityprotectedandcipheredwithnew5GNASsecuritycontext=4, +} Security_header_t; + +typedef enum { + SUCI=1, + SGGUTI, + IMEI, + SGSTMSI, + IMEISV, + MACaddress, + EUI64, +} identitytype_t; + + +// table 9.11.3.2.1 +#define FOREACH_CAUSE(CAUSE_DEF) \ + CAUSE_DEF(Illegal_UE,0x3 )\ + CAUSE_DEF(PEI_not_accepted,0x5 )\ + CAUSE_DEF(Illegal_ME,0x6 )\ + CAUSE_DEF(SGS_services_not_allowed,0x7 )\ + CAUSE_DEF(UE_identity_cannot_be_derived_by_the_network,0x9 )\ + CAUSE_DEF(Implicitly_de_registered,0x0a )\ + CAUSE_DEF(PLMN_not_allowed,0x0b )\ + CAUSE_DEF(Tracking_area_not_allowed,0x0c )\ + CAUSE_DEF(Roaming_not_allowed_in_this_tracking_area,0x0d )\ + CAUSE_DEF(No_suitable_cells_in_tracking_area,0x0f )\ + CAUSE_DEF(MAC_failure,0x14 )\ + CAUSE_DEF(Synch_failure,0x15 )\ + CAUSE_DEF(Congestion,0x16 )\ + CAUSE_DEF(UE_security_capabilities_mismatch,0x17 )\ + CAUSE_DEF(Security_mode_rejected_unspecified,0x18 )\ + CAUSE_DEF(Non_5G_authentication_unacceptable,0x1a )\ + CAUSE_DEF(N1_mode_not_allowed,0x1b )\ + CAUSE_DEF(Restricted_service_area,0x1c )\ + CAUSE_DEF(Redirection_to_EPC_required,0x1f )\ + CAUSE_DEF(LADN_not_available,0x2b )\ + CAUSE_DEF(No_network_slices_available,0x3e )\ + CAUSE_DEF(Maximum_number_of_PDU_sessions_reached,0x41 )\ + CAUSE_DEF(Insufficient_resources_for_specific_slice_and_DNN,0x43 )\ + CAUSE_DEF(Insufficient_resources_for_specific_slice,0x45 )\ + CAUSE_DEF(ngKSI_already_in_use,0x47 )\ + CAUSE_DEF(Non_3GPP_access_to_5GCN_not_allowed,0x48 )\ + CAUSE_DEF(Serving_network_not_authorized,0x49 )\ + CAUSE_DEF(Temporarily_not_authorized_for_this_SNPN,0x4A )\ + CAUSE_DEF(Permanently_not_authorized_for_this_SNPN,0x4b )\ + CAUSE_DEF(Not_authorized_for_this_CAG_or_authorized_for_CAG_cells_only,0x4c )\ + CAUSE_DEF(Wireline_access_area_not_allowed,0x4d )\ + CAUSE_DEF(Payload_was_not_forwarded,0x5a )\ + CAUSE_DEF(DNN_not_supported_or_not_subscribed_in_the_slice,0x5b )\ + CAUSE_DEF(Insufficient_user_plane_resources_for_the_PDU_session,0x5c )\ + CAUSE_DEF(Semantically_incorrect_message,0x5f )\ + CAUSE_DEF(Invalid_mandatory_information,0x60 )\ + CAUSE_DEF(Message_type_non_existent_or_not_implemented,0x61 )\ + CAUSE_DEF(Message_type_not_compatible_with_the_protocol_state,0x62 )\ + CAUSE_DEF(Information_element_non_existent_or_not_implemented,0x63 )\ + CAUSE_DEF(Conditional_IE_error,0x64 )\ + CAUSE_DEF(Message_not_compatible_with_the_protocol_state,0x65 )\ + CAUSE_DEF(Protocol_error_unspecified,0x67 ) + +/* Map task id to printable name. */ + +#define CAUSE_TEXT(LabEl, nUmID) {nUmID, #LabEl}, + +static const text_info_t cause_text_info[] = { + FOREACH_CAUSE(TO_TEXT) +}; + +#define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID, +//! Tasks id of each task +typedef enum { + FOREACH_CAUSE(TO_ENUM) +} cause_id_t; + +//_table_9.11.4.2.1:_5GSM_cause_information_element +#define FOREACH_CAUSE_SECU(CAUSE_SECU_DEF) \ + CAUSE_SECU_DEF(Security_Operator_determined_barring,0x08 )\ + CAUSE_SECU_DEF(Security_Insufficient_resources,0x1a )\ + CAUSE_SECU_DEF(Security_Missing_or_unknown_DNN,0x1b )\ + CAUSE_SECU_DEF(Security_Unknown_PDU_session_type,0x1c )\ + CAUSE_SECU_DEF(Security_User_authentication_or_authorization_failed,0x1d )\ + CAUSE_SECU_DEF(Security_Request_rejected_unspecified,0x1f )\ + CAUSE_SECU_DEF(Security_Service_option_not_supported,0x20 )\ + CAUSE_SECU_DEF(Security_Requested_service_option_not_subscribed,0x21 )\ + CAUSE_SECU_DEF(Security_Service_option_temporarily_out_of_order,0x22 )\ + CAUSE_SECU_DEF(Security_PTI_already_in_use,0x23 )\ + CAUSE_SECU_DEF(Security_Regular_deactivation,0x24 )\ + CAUSE_SECU_DEF(Security_Network_failure,0x26 )\ + CAUSE_SECU_DEF(Security_Reactivation_requested,0x27 )\ + CAUSE_SECU_DEF(Security_Semantic_error_in_the_TFT_operation,0x29 )\ + CAUSE_SECU_DEF(Security_Syntactical_error_in_the_TFT_operation,0x2a )\ + CAUSE_SECU_DEF(Security_Invalid_PDU_session_identity,0x2b )\ + CAUSE_SECU_DEF(Security_Semantic_errors_in_packet_filter,0x2c )\ + CAUSE_SECU_DEF(Security_Syntactical_error_in_packet_filter,0x2d )\ + CAUSE_SECU_DEF(Security_Out_of_LADN_service_area,0x2e )\ + CAUSE_SECU_DEF(Security_PTI_mismatch,0x2f )\ + CAUSE_SECU_DEF(Security_PDU_session_type_IPv4_only_allowed,0x32 )\ + CAUSE_SECU_DEF(Security_PDU_session_type_IPv6_only_allowed,0x33 )\ + CAUSE_SECU_DEF(Security_PDU_session_does_not_exist,0x36 )\ + CAUSE_SECU_DEF(Security_PDU_session_type_IPv4v6_only_allowed,0x39 )\ + CAUSE_SECU_DEF(Security_PDU_session_type_Unstructured_only_allowed,0x3a )\ + CAUSE_SECU_DEF(Security_PDU_session_type_Ethernet_only_allowed,0x3d )\ + CAUSE_SECU_DEF(Security_Insufficient_resources_for_specific_slice_and_DNN,0x43 )\ + CAUSE_SECU_DEF(Security_Not_supported_SSC_mode,0x44 )\ + CAUSE_SECU_DEF(Security_Insufficient_resources_for_specific_slice,0x45 )\ + CAUSE_SECU_DEF(Security_Missing_or_unknown_DNN_in_a_slice,0x46 )\ + CAUSE_SECU_DEF(Security_Invalid_PTI_value,0x51 )\ + CAUSE_SECU_DEF(Security_Maximum_data_rate_per_UE_for_user_plane_integrity_protection_is_too_low,0x52 )\ + CAUSE_SECU_DEF(Security_Semantic_error_in_the_QoS_operation,0x53 )\ + CAUSE_SECU_DEF(Security_Syntactical_error_in_the_QoS_operation,0x54 )\ + CAUSE_SECU_DEF(Security_Invalid_mapped_EPS_bearer_identity,0x55 )\ + CAUSE_SECU_DEF(Security_Semantically_incorrect_message,0x5f )\ + CAUSE_SECU_DEF(Security_Invalid_mandatory_information,0x60 )\ + CAUSE_SECU_DEF(Security_Message_type_non_existent_or_not_implemented,0x61 )\ + CAUSE_SECU_DEF(Security_Message_type_not_compatible_with_the_protocol_state,0x62 )\ + CAUSE_SECU_DEF(Security_Information_element_non_existent_or_not_implemented,0x63 )\ + CAUSE_SECU_DEF(Security_Conditional_IE_error,0x64 )\ + CAUSE_SECU_DEF(Security_Message_not_compatible_with_the_protocol_state,0x65 )\ + CAUSE_SECU_DEF(Security_Protocol_error_unspecified,0x6f ) + +static const text_info_t cause_secu_text_info[] = { + FOREACH_CAUSE_SECU(TO_TEXT) +}; + +//! Tasks id of each task +typedef enum { + FOREACH_CAUSE_SECU(TO_ENUM) +} cause_secu_id_t; + +// IEI (information element identifier) are spread in each message definition +#define IEI_RAND 0x21 +#define IEI_AUTN 0x20 +#define IEI_EAP 0x78 +#define IEI_AuthenticationResponse 0x2d + +//TS 24.501 sub layer states for UE +// for network side, only 5GMMderegistered, 5GMMderegistered_initiated, 5GMMregistered, 5GMMservice_request_initiated are valid +typedef enum { + SGMMnull, + SGMMderegistered, + SGMMderegistered_initiated, + SGMMregistered, + SGMMregistered_initiated, + SGMMservice_request_initiated, +} SGMM_UE_states; + +typedef struct { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; +} SGScommonHeader_t; + +typedef struct { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + identitytype_t it:8; +} Identityrequest_t; + +// the message continues with the identity value, depending on identity type, see TS 14.501, 9.11.3.4 +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + uint16_t len; +} +Identityresponse_t; + +typedef struct __attribute__((packed)) { + Identityresponse_t common; + identitytype_t mi:8; + unsigned int supiFormat:4; + unsigned int identityType:4; + unsigned int mcc1:4; + unsigned int mcc2:4; + unsigned int mcc3:4; + unsigned int mnc3:4; + unsigned int mnc1:4; + unsigned int mnc2:4; + unsigned int routing1:4; + unsigned int routing2:4; + unsigned int routing3:4; + unsigned int routing4:4; + unsigned int protectScheme:4; + unsigned int spare:4; + uint8_t hplmnId; +} +IdentityresponseIMSI_t; + +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + unsigned int ngKSI:4; + unsigned int spare:4; + unsigned int ABBALen:8; + unsigned int ABBA:16; + uint8_t ieiRAND; + uint8_t RAND[16]; + uint8_t ieiAUTN; + uint8_t AUTNlen; + uint8_t AUTN[16]; +} +authenticationrequestHeader_t; + +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + uint8_t iei; + uint8_t RESlen; + uint8_t RES[16]; +} authenticationresponse_t; + +//AUTHENTICATION RESULT + +typedef struct __attribute__((packed)) { + Extendedprotocoldiscriminator_t epd:8; + Security_header_t sh:8; + SGSmobilitymanagementmessages_t mt:8; + + unsigned int selectedNASsecurityalgorithms; + unsigned int ngKSI:4; //ngKSI NAS key set identifier 9.11.3.32 + unsigned int spare:4; + // LV 3-9 bytes Replayed UE security capabilities UE security capability 9.11.3.54 + + /* optional + TV (E-, 1 byte) Oprional IMEISV request IMEISV request 9.11.3.28 + TV (57, 2 bytes ) Selected EPS NAS security algorithms EPS NAS security algorithms 9.11.3.25 + TLV (36, 3 bytes) Additional 5G security information Additional 5G security information 9.11.3.12 + TLV-E (78,, 7-1503 bytes) EAP message EAP message 9.11.2.2 + TLV (38, 4-n)ABBA ABBA 9.11.3.10 + TLV (19, 4-7) Replayed S1 UE security capabilities S1 UE security capability 9.11.3.48A + */ + +} securityModeCommand_t; + +typedef struct { + uicc_t *uicc; +} nr_user_nas_t; + +#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed") +#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1); +#define arrayCpy(tO, FroM) STATIC_ASSERT(sizeof(tO) == sizeof(FroM)) ; memcpy(tO, FroM, sizeof(tO)) +int resToresStar(uint8_t *msg, uicc_t* uicc); + +int identityResponse(void **msg, nr_user_nas_t *UE); +int authenticationResponse(void **msg, nr_user_nas_t *UE); +void UEprocessNAS(void *msg,nr_user_nas_t *UE); +void SGSabortUE(void *msg, NRUEcontext_t *UE) ; +void SGSregistrationReq(void *msg, NRUEcontext_t *UE); +void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE); +void SGSauthenticationResp(void *msg, NRUEcontext_t *UE); +void SGSidentityResp(void *msg, NRUEcontext_t *UE); +void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE); +void SGSregistrationComplete(void *msg, NRUEcontext_t *UE); +void processNAS(void *msg, NRUEcontext_t *UE); +int identityRequest(void **msg, NRUEcontext_t *UE); +int authenticationRequest(void **msg, NRUEcontext_t *UE); +int securityModeCommand(void **msg, NRUEcontext_t *UE); + +#endif diff --git a/openair3/NAS/COMMON/milenage.h b/openair3/NAS/COMMON/milenage.h new file mode 100644 index 0000000000..c5762a0d69 --- /dev/null +++ b/openair3/NAS/COMMON/milenage.h @@ -0,0 +1,355 @@ +/* + Adaptatipn of SW from hereafter license + Author: laurent.thomas@open-cells.com + The OpenAirInterface project uses this copy under the terms of BSD + license. +*/ +/* + 3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208) + Copyright (c) 2006-2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Alternatively, this software may be distributed under the terms of BSD + license. + + See README and COPYING for more details. + + This file implements an example authentication algorithm defined for 3GPP + AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow + EAP-AKA to be tested properly with real USIM cards. + + This implementations assumes that the r1..r5 and c1..c5 constants defined in + TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00, + c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to + be AES (Rijndael). +*/ + +#ifndef MILENAGE_H +#define MILENAGE_H +#include + + +#define u8 uint8_t +/** + milenage_f1 - Milenage f1 and f1* algorithms + @opc: OPc = 128-bit value derived from OP and K + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @sqn: SQN = 48-bit sequence number + @amf: AMF = 16-bit authentication management field + @mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL + @mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL + Returns: true on success, false on failure +*/ + +void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) { + AES_KEY k; + u8 tmp[16]; + AES_set_encrypt_key(key, 128, &k); + AES_encrypt(in, tmp, &k); + memcpy(out, tmp, sizeof(tmp)); +} +static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, + const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) { + u8 tmp1[16], tmp2[16], tmp3[16]; + int i; + + /* tmp1 = TEMP = E_K(RAND XOR OP_C) */ + for (i = 0; i < 16; i++) + tmp1[i] = _rand[i] ^ opc[i]; + + aes_128_encrypt_block(k, tmp1, tmp1); + AES_KEY kTab; + uint8_t cyphered[16]; + AES_set_encrypt_key(k, 128, &kTab); + AES_encrypt(tmp1, cyphered, &kTab); + /* tmp2 = IN1 = SQN || AMF || SQN || AMF */ + memcpy(tmp2, sqn, 6); + memcpy(tmp2 + 6, amf, 2); + memcpy(tmp2 + 8, tmp2, 8); + + /* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */ + + /* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */ + for (i = 0; i < 16; i++) + tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i]; + + /* XOR with TEMP = E_K(RAND XOR OP_C) */ + for (i = 0; i < 16; i++) + tmp3[i] ^= tmp1[i]; + + /* XOR with c1 (= ..00, i.e., NOP) */ + /* f1 || f1* = E_K(tmp3) XOR OP_c */ + aes_128_encrypt_block(k, tmp3, tmp1); + + for (i = 0; i < 16; i++) + tmp1[i] ^= opc[i]; + + if (mac_a) + memcpy(mac_a, tmp1, 8); /* f1 */ + + if (mac_s) + memcpy(mac_s, tmp1 + 8, 8); /* f1* */ + + return true; +} + + +/** + milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms + @opc: OPc = 128-bit value derived from OP and K + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @res: Buffer for RES = 64-bit signed response (f2), or %NULL + @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL + @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL + @ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL + @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL + Returns: true on success, false on failure +*/ +static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, + u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar) { + u8 tmp1[16], tmp2[16], tmp3[16]; + int i; + + /* tmp2 = TEMP = E_K(RAND XOR OP_C) */ + for (i = 0; i < 16; i++) + tmp1[i] = _rand[i] ^ opc[i]; + + aes_128_encrypt_block(k, tmp1, tmp2); + + /* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */ + /* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */ + /* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */ + /* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */ + + /* f2 and f5 */ + /* rotate by r2 (= 0, i.e., NOP) */ + for (i = 0; i < 16; i++) + tmp1[i] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 1; /* XOR c2 (= ..01) */ + /* f5 || f2 = E_K(tmp1) XOR OP_c */ + aes_128_encrypt_block(k, tmp1, tmp3); + + for (i = 0; i < 16; i++) + tmp3[i] ^= opc[i]; + + if (res) + memcpy(res, tmp3 + 8, 8); /* f2 */ + + if (ak) + memcpy(ak, tmp3, 6); /* f5 */ + + /* f3 */ + if (ck) { + /* rotate by r3 = 0x20 = 4 bytes */ + for (i = 0; i < 16; i++) + tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 2; /* XOR c3 (= ..02) */ + aes_128_encrypt_block(k, tmp1, ck); + + for (i = 0; i < 16; i++) + ck[i] ^= opc[i]; + } + + /* f4 */ + if (ik) { + /* rotate by r4 = 0x40 = 8 bytes */ + for (i = 0; i < 16; i++) + tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 4; /* XOR c4 (= ..04) */ + aes_128_encrypt_block(k, tmp1, ik); + + for (i = 0; i < 16; i++) + ik[i] ^= opc[i]; + } + + /* f5* */ + if (akstar) { + /* rotate by r5 = 0x60 = 12 bytes */ + for (i = 0; i < 16; i++) + tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i]; + + tmp1[15] ^= 8; /* XOR c5 (= ..08) */ + aes_128_encrypt_block(k, tmp1, tmp1); + + for (i = 0; i < 6; i++) + akstar[i] = tmp1[i] ^ opc[i]; + } + + return true; +} + + +/** + milenage_generate - Generate AKA AUTN,IK,CK,RES + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @amf: AMF = 16-bit authentication management field + @k: K = 128-bit subscriber key + @sqn: SQN = 48-bit sequence number + @_rand: RAND = 128-bit random challenge + @autn: Buffer for AUTN = 128-bit authentication token + @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL + @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL + @res: Buffer for RES = 64-bit signed response (f2), or %NULL + @res_len: Max length for res; set to used length or 0 on failure +*/ +static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, + const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik, + u8 *ck, u8 *res) { + int i; + u8 mac_a[8], ak[6]; + + if (!milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) || + !milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) + return false; + + /* AUTN = (SQN ^ AK) || AMF || MAC */ + for (i = 0; i < 6; i++) + autn[i] = sqn[i] ^ ak[i]; + + memcpy(autn + 6, amf, 2); + memcpy(autn + 8, mac_a, 8); + return true; +} + + +/** + milenage_auts - Milenage AUTS validation + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @auts: AUTS = 112-bit authentication token from client + @sqn: Buffer for SQN = 48-bit sequence number + Returns: 0 = success (sqn filled), -1 on failure +*/ +#define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5])); +// valid code but put in comment as it is not used right now +#if 0 +static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts, + u8 *sqn) { + u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + u8 ak[6], mac_s[8]; + int i; + + if (!milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) + return false; + + for (i = 0; i < 6; i++) + sqn[i] = auts[i] ^ ak[i]; + + //p(sqn); + if (!milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) || + memcmp(mac_s, auts + 6, 8) != 0) + return false; + + return true; +} + + +/** + gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @k: K = 128-bit subscriber key + @_rand: RAND = 128-bit random challenge + @sres: Buffer for SRES = 32-bit SRES + @kc: Buffer for Kc = 64-bit Kc + Returns: 0 on success, -1 on failure +*/ +static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) { + u8 res[8], ck[16], ik[16]; + int i; + + if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL)) + return false; + + for (i = 0; i < 8; i++) + kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8]; + +#ifdef GSM_MILENAGE_ALT_SRES + memcpy(sres, res, 4); +#else /* GSM_MILENAGE_ALT_SRES */ + + for (i = 0; i < 4; i++) + sres[i] = res[i] ^ res[i + 4]; + +#endif /* GSM_MILENAGE_ALT_SRES */ + return true; +} + + +/** + milenage_generate - Generate AKA AUTN,IK,CK,RES + @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) + @k: K = 128-bit subscriber key + @sqn: SQN = 48-bit sequence number + @_rand: RAND = 128-bit random challenge + @autn: AUTN = 128-bit authentication token + @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL + @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL + @res: Buffer for RES = 64-bit signed response (f2), or %NULL + @res_len: Variable that will be set to RES length + @auts: 112-bit buffer for AUTS + Returns: 0 on success, -1 on failure, or -2 on synchronization failure +*/ +static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand, + const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len, + u8 *auts) { + int i; + u8 mac_a[8], ak[6], rx_sqn[6]; + const u8 *amf; + + if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) + return -1; + + *res_len = 8; + + /* AUTN = (SQN ^ AK) || AMF || MAC */ + for (i = 0; i < 6; i++) + rx_sqn[i] = autn[i] ^ ak[i]; + + if (memcmp(rx_sqn, sqn, 6) <= 0) { + u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + + if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) + return -1; + + for (i = 0; i < 6; i++) + auts[i] = sqn[i] ^ ak[i]; + + if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6)) + return -1; + + return -2; + } + + amf = autn + 6; + + if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL)) + return -1; + + if (memcmp(mac_a, autn + 8, 8) != 0) { + printf( "Milenage: MAC mismatch\n"); + return -1; + } + + return 0; +} + +static void milenage_opc_gen(const u8 *k, const u8 *op, u8 *opc) { + int i; + /* Encrypt OP using K */ + aes_128_encrypt_block(k, op, opc); + + /* XOR the resulting Ek(OP) with OP */ + for (i = 0; i < 16; i++) + opc[i] = opc[i] ^ op[i]; +} +#endif +#endif diff --git a/openair3/NAS/COMMON/nr_common.c b/openair3/NAS/COMMON/nr_common.c new file mode 100644 index 0000000000..736d75f6cc --- /dev/null +++ b/openair3/NAS/COMMON/nr_common.c @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include + +void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size) { + //SNN-network-identifier in TS 24.501 + // TS 24.501: If the MNC of the serving PLMN has two digits, then a zero is added at the beginning. + const char *format="5G:mnc000.mcc000.3gppnetwork.org"; + memcpy(msg,format, strlen(format)); + + if (nmc_size == 2) + memcpy(msg+7, imsiStr+3, 2); + else + memcpy(msg+6, imsiStr+3, 3); + + memcpy(msg+13, imsiStr, 3); +} + +int resToresStar(uint8_t *msg, uicc_t* uicc) { + // TS 33.220 annex B.2 => FC=0x6B in TS 33.501 annex A.4 + //input S to KDF + uint8_t S[128]= {0}; + S[0]=0x6B; + uint8_t *ptr=S+1; + servingNetworkName(ptr, uicc->imsiStr, uicc->nmc_size); + *(uint16_t *)(ptr+strlen((char *)ptr))=htons(strlen((char *)ptr)); + ptr+=strlen((char *)ptr)+sizeof(uint16_t); + // add rand + memcpy(ptr, uicc->rand, sizeof(uicc->rand) ) ; + *(uint16_t *)(ptr+sizeof(uicc->rand))=htons(sizeof(uicc->rand)); + ptr+=sizeof(uicc->rand)+sizeof(uint16_t); + // add res + memcpy(ptr, uicc->milenage_res, sizeof(uicc->milenage_res) ) ; + *(uint16_t *)(ptr+sizeof(uicc->milenage_res))=htons(sizeof(uicc->milenage_res)); + ptr+=sizeof(uicc->milenage_res)+sizeof(uint16_t); + // S is done + uint8_t ckik[sizeof(uicc->ck) +sizeof(uicc->ik)]; + memcpy(ckik, uicc->ck, sizeof(uicc->ck)); + memcpy(ckik+sizeof(uicc->ck),uicc->ik, sizeof(uicc->ik)); + uint8_t out[32]; + kdf(S, ptr-S, ckik, 32, out, sizeof(out)); + memcpy(msg, out+16, 16); + return 16; +} diff --git a/common/utils/itti_analyzer/AUTHORS b/openair3/NAS/NR_UE/.gitkeep similarity index 100% rename from common/utils/itti_analyzer/AUTHORS rename to openair3/NAS/NR_UE/.gitkeep diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c new file mode 100644 index 0000000000..2c07de8dd5 --- /dev/null +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -0,0 +1,692 @@ +/* + * 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_nas_msg_sim.c + * \brief simulator for nr nas message + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + +#include // memset +#include // malloc, free + +#include "nas_log.h" +#include "TLVDecoder.h" +#include "TLVEncoder.h" +#include "nr_nas_msg_sim.h" +#include "aka_functions.h" +#include "secu_defs.h" +#include "PduSessionEstablishRequest.h" +char netName[] = "5G:mnc093.mcc208.3gppnetwork.org"; +char imsi[] = "2089300007487"; +// USIM_API_K: 5122250214c33e723a5dd523fc145fc0 +uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0}; +// OPC: 981d464c7c52eb6e5036234984ad0bcf +const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf}; + +uint8_t *registration_request_buf; +uint32_t registration_request_len; + +static int nas_protected_security_header_encode( + char *buffer, + const fgs_nas_message_security_header_t *header, + int length) +{ + LOG_FUNC_IN; + + int size = 0; + + /* Encode the protocol discriminator) */ + ENCODE_U8(buffer, header->protocol_discriminator, size); + + /* Encode the security header type */ + ENCODE_U8(buffer+size, (header->security_header_type & 0xf), size); + + /* Encode the message authentication code */ + ENCODE_U32(buffer+size, header->message_authentication_code, size); + /* Encode the sequence number */ + ENCODE_U8(buffer+size, header->sequence_number, size); + + LOG_FUNC_RETURN (size); +} + +static int _nas_mm_msg_encode_header(const mm_msg_header_t *header, + uint8_t *buffer, uint32_t len) { + int size = 0; + + /* Check the buffer length */ + if (len < sizeof(mm_msg_header_t)) { + return (TLV_ENCODE_BUFFER_TOO_SHORT); + } + + /* Check the protocol discriminator */ + if (header->ex_protocol_discriminator != FGS_MOBILITY_MANAGEMENT_MESSAGE) { + LOG_TRACE(ERROR, "ESM-MSG - Unexpected extened protocol discriminator: 0x%x", + header->ex_protocol_discriminator); + return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED); + } + + /* Encode the extendedprotocol discriminator */ + ENCODE_U8(buffer + size, header->ex_protocol_discriminator, size); + /* Encode the security header type */ + ENCODE_U8(buffer + size, (header->security_header_type & 0xf), size); + /* Encode the message type */ + ENCODE_U8(buffer + size, header->message_type, size); + return (size); +} + + +int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { + LOG_FUNC_IN; + int header_result; + int encode_result; + uint8_t msg_type = mm_msg->header.message_type; + + + /* First encode the EMM message header */ + header_result = _nas_mm_msg_encode_header(&mm_msg->header, buffer, len); + + if (header_result < 0) { + LOG_TRACE(ERROR, "EMM-MSG - Failed to encode EMM message header " + "(%d)", header_result); + LOG_FUNC_RETURN(header_result); + } + + buffer += header_result; + len -= header_result; + + switch(msg_type) { + case REGISTRATION_REQUEST: + encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len); + break; + case FGS_IDENTITY_RESPONSE: + encode_result = encode_identiy_response(&mm_msg->fgs_identity_response, buffer, len); + break; + case FGS_AUTHENTICATION_RESPONSE: + encode_result = encode_fgs_authentication_response(&mm_msg->fgs_auth_response, buffer, len); + break; + case FGS_SECURITY_MODE_COMPLETE: + encode_result = encode_fgs_security_mode_complete(&mm_msg->fgs_security_mode_complete, buffer, len); + break; + case FGS_UPLINK_NAS_TRANSPORT: + encode_result = encode_fgs_uplink_nas_transport(&mm_msg->uplink_nas_transport, buffer, len); + break; + default: + LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", + mm_msg->header.message_type); + encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE; + break; + /* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */ + } + + if (encode_result < 0) { + LOG_TRACE(ERROR, "EMM-MSG - Failed to encode L3 EMM message 0x%x " + "(%d)", mm_msg->header.message_type, encode_result); + } + + if (encode_result < 0) + LOG_FUNC_RETURN (encode_result); + + LOG_FUNC_RETURN (header_result + encode_result); +} + +void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) { + uint8_t S[100]; + S[0] = 0x6B; + int netNamesize = strlen(netName); + memcpy(&S[1], netName, netNamesize); + S[1 + netNamesize] = (netNamesize & 0xff00) >> 8; + S[2 + netNamesize] = (netNamesize & 0x00ff); + for (int i = 0; i < 16; i++) + S[3 + netNamesize + i] = rand[i]; + S[19 + netNamesize] = 0x00; + S[20 + netNamesize] = 0x10; + for (int i = 0; i < 8; i++) + S[21 + netNamesize + i] = input[i]; + S[29 + netNamesize] = 0x00; + S[30 + netNamesize] = 0x08; + + uint8_t plmn[3] = { 0x02, 0xf8, 0x39 }; + uint8_t oldS[100]; + oldS[0] = 0x6B; + memcpy(&oldS[1], plmn, 3); + oldS[4] = 0x00; + oldS[5] = 0x03; + for (int i = 0; i < 16; i++) + oldS[6 + i] = rand[i]; + oldS[22] = 0x00; + oldS[23] = 0x10; + for (int i = 0; i < 8; i++) + oldS[24 + i] = input[i]; + oldS[32] = 0x00; + oldS[33] = 0x08; + + + uint8_t key[32]; + memcpy(&key[0], ck, 16); + memcpy(&key[16], ik, 16); //KEY + uint8_t out[32]; + kdf(key, 32, S, 31 + netNamesize, out, 32); + for (int i = 0; i < 16; i++) + output[i] = out[16 + i]; +} + +void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) { + uint8_t S[100]; + uint8_t key[32]; + int netNamesize = strlen(netName); + memcpy(&key[0], ck, 16); + memcpy(&key[16], ik, 16); //KEY + S[0] = 0x6A; + memcpy(&S[1], netName, netNamesize); + S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); + S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); + for (int i = 0; i < 6; i++) { + S[3 + netNamesize + i] = sqn[i]; + } + S[9 + netNamesize] = 0x00; + S[10 + netNamesize] = 0x06; + kdf(key, 32, S, 11 + netNamesize, kausf, 32); +} + +void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) { + uint8_t S[100]; + int netNamesize = strlen(netName); + S[0] = 0x6C; //FC + memcpy(&S[1], netName, netNamesize); + S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); + S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); + kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32); +} + +void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) { + int imsiLen = strlen(imsi); + uint8_t S[100]; + S[0] = 0x6D; //FC = 0x6D + memcpy(&S[1], imsi, imsiLen); + S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8); + S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff); + S[3 + imsiLen] = abba & 0x00ff; + S[4 + imsiLen] = (abba & 0xff00) >> 8; + S[5 + imsiLen] = 0x00; + S[6 + imsiLen] = 0x02; + kdf(kseaf, 32, S, 7 + imsiLen, kamf, 32); +} + +//------------------------------------------------------------------------------ +void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas_int) { + uint8_t S[20]; + uint8_t out[32] = { 0 }; + S[0] = 0x69; //FC + S[1] = (uint8_t)(nas_alg_type & 0xFF); + S[2] = 0x00; + S[3] = 0x01; + S[4] = nas_alg_id; + S[5] = 0x00; + S[6] = 0x01; + kdf(kamf, 32, S, 7, out, 32); + for (int i = 0; i < 16; i++) + knas_int[i] = out[16 + i]; +} + +void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { + int size = sizeof(mm_msg_header_t); + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + MM_msg *mm_msg; + + mm_msg = &nas_msg.plain.mm_msg; + // set header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = REGISTRATION_REQUEST; + + + // set registration request + mm_msg->registration_request.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->registration_request.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->registration_request.messagetype = REGISTRATION_REQUEST; + size += 1; + mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION; + mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1; + size += 1; + if(1){ + mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI; + mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 0xca; + mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 0; + mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1016; + mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10; + mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9; + mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3; + mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = 0xf; + mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2; + mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0; + mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8; + + size += 13; + + } else { + mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI; + mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9; + mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 3; + mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf; + mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2; + mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0; + mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = 8; + mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput = 0x4778; + + size += 14; + } + + mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT; + mm_msg->registration_request.fgmmcapability.iei = REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI; + mm_msg->registration_request.fgmmcapability.length = 1; + mm_msg->registration_request.fgmmcapability.value = 0x7; + size += 3; + + mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_PRESENT; + mm_msg->registration_request.nruesecuritycapability.iei = REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI; + mm_msg->registration_request.nruesecuritycapability.length = 8; + mm_msg->registration_request.nruesecuritycapability.fg_EA = 0x80; + mm_msg->registration_request.nruesecuritycapability.fg_IA = 0x20; + mm_msg->registration_request.nruesecuritycapability.EEA = 0; + mm_msg->registration_request.nruesecuritycapability.EIA = 0; + size += 10; + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + registration_request_buf = initialNasMsg->data; + + initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); + registration_request_len = initialNasMsg->length; + +} + +void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype) { + int size = sizeof(mm_msg_header_t); + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + MM_msg *mm_msg; + + mm_msg = &nas_msg.plain.mm_msg; + // set header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = FGS_IDENTITY_RESPONSE; + + + // set identity response + mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->fgs_identity_response.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->fgs_identity_response.messagetype = FGS_IDENTITY_RESPONSE; + size += 1; + if(identitytype == FGS_MOBILE_IDENTITY_SUCI){ + mm_msg->fgs_identity_response.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = 9; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 3; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = 0xf; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = 8; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.schemeoutput = 0x4778; + + size += 14; + } + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + + initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); + +} + +OctetString knas_int; +void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){ + + uint8_t ak[6]; + + uint8_t kausf[32]; + uint8_t sqn[6]; + uint8_t kseaf[32]; + uint8_t kamf[32]; + OctetString res; + + // get RAND for authentication request + unsigned char rand[16]; + for(int index = 0; index < 16;index++){ + rand[index] = buf[8+index]; + } + + uint8_t resTemp[16]; + uint8_t ck[16], ik[16], output[16]; + f2345(k, rand, resTemp, ck, ik, ak, opc); + + transferRES(ck, ik, resTemp, rand, output); + + // get knas_int + knas_int.length = 16; + knas_int.value = malloc(knas_int.length); + for(int index = 0; index < 6; index++){ + sqn[index] = buf[26+index]; + } + + derive_kausf(ck, ik, sqn, kausf); + derive_kseaf(kausf, kseaf); + derive_kamf(kseaf, kamf, 0x0000); + derive_knas(0x02, 2, kamf, knas_int.value); + + printf("kausf:"); + for(int i = 0; i < 32; i++){ + printf("%x ", kausf[i]); + } + printf("\n"); + + printf("kseaf:"); + for(int i = 0; i < 32; i++){ + printf("%x ", kseaf[i]); + } + + printf("\n"); + + printf("kamf:"); + for(int i = 0; i < 32; i++){ + printf("%x ", kamf[i]); + } + printf("\n"); + + printf("knas_int:\n"); + for(int i = 0; i < 16; i++){ + printf("%x ", knas_int.value[i]); + } + printf("\n"); + + // set res + res.length = 16; + res.value = output; + + int size = sizeof(mm_msg_header_t); + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + MM_msg *mm_msg; + + mm_msg = &nas_msg.plain.mm_msg; + // set header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = FGS_AUTHENTICATION_RESPONSE; + + // set authentication response + mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->fgs_identity_response.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->fgs_identity_response.messagetype = FGS_AUTHENTICATION_RESPONSE; + size += 1; + + //set response parameter + mm_msg->fgs_auth_response.authenticationresponseparameter.res = res; + size += 18; + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + + initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); +} + +void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) +{ + int size = sizeof(mm_msg_header_t); + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + + MM_msg *mm_msg; + nas_stream_cipher_t stream_cipher; + uint8_t mac[4]; + // set security protected header + nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX; + size += 7; + + mm_msg = &nas_msg.security_protected.plain.mm_msg; + + // set header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = FGS_SECURITY_MODE_COMPLETE; + + // set security mode complete + mm_msg->fgs_security_mode_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->fgs_security_mode_complete.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->fgs_security_mode_complete.messagetype = FGS_SECURITY_MODE_COMPLETE; + size += 1; + + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit1 = 1; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp1 = 1; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp = 1; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.oddeven = 0; + size += 5; + + mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf; + mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = registration_request_len; + size += (registration_request_len + 2); + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + + int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size); + + initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); + + stream_cipher.key = knas_int.value; + stream_cipher.key_length = 16; + stream_cipher.count = 0; + stream_cipher.bearer = 1; + stream_cipher.direction = 0; + stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6); + /* length in bits */ + stream_cipher.blength = (initialNasMsg->length - 6) << 3; + + // only for Type of integrity protection algorithm: 128-5G-IA2 (2) + nas_stream_encrypt_eia2( + &stream_cipher, + mac); + + printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); + for(int i = 0; i < 4; i++){ + initialNasMsg->data[2+i] = mac[i]; + } +} + +void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) { + //wait send RRCReconfigurationComplete and InitialContextSetupResponse + sleep(1); + int length = 0; + int size = 0; + fgs_nas_message_t nas_msg; + nas_stream_cipher_t stream_cipher; + uint8_t mac[4]; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + fgs_nas_message_security_protected_t *sp_msg; + + sp_msg = &nas_msg.security_protected; + // set header + sp_msg->header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + sp_msg->header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED; + sp_msg->header.message_authentication_code = 0; + sp_msg->header.sequence_number = 1; + length = 7; + sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + length += 1; + sp_msg->plain.mm_msg.registration_complete.securityheadertype = PLAIN_5GS_MSG; + sp_msg->plain.mm_msg.registration_complete.sparehalfoctet = 0; + length += 1; + sp_msg->plain.mm_msg.registration_complete.messagetype = REGISTRATION_COMPLETE; + length += 1; + + if(sortransparentcontainer) { + length += sortransparentcontainer->sortransparentcontainercontents.length; + } + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(length * sizeof(Byte_t)); + + /* Encode the first octet of the header (extended protocol discriminator) */ + ENCODE_U8(initialNasMsg->data + size, sp_msg->header.protocol_discriminator, size); + + /* Encode the security header type */ + ENCODE_U8(initialNasMsg->data + size, sp_msg->header.security_header_type, size); + + /* Encode the message authentication code */ + ENCODE_U32(initialNasMsg->data + size, sp_msg->header.message_authentication_code, size); + + /* Encode the sequence number */ + ENCODE_U8(initialNasMsg->data + size, sp_msg->header.sequence_number, size); + + + /* Encode the extended protocol discriminator */ + ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator, size); + + /* Encode the security header type */ + ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.securityheadertype, size); + + /* Encode the message type */ + ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.messagetype, size); + + if(sortransparentcontainer) { + encode_registration_complete(&sp_msg->plain.mm_msg.registration_complete, initialNasMsg->data + size, length - size); + } + + initialNasMsg->length = length; + stream_cipher.key = knas_int.value; + stream_cipher.key_length = 16; + stream_cipher.count = 1; + stream_cipher.bearer = 1; + stream_cipher.direction = 0; + stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6); + /* length in bits */ + stream_cipher.blength = (initialNasMsg->length - 6) << 3; + + // only for Type of integrity protection algorithm: 128-5G-IA2 (2) + nas_stream_encrypt_eia2( + &stream_cipher, + mac); + + printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); + for(int i = 0; i < 4; i++){ + initialNasMsg->data[2+i] = mac[i]; + } +} + +void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){ + //wait send RegistrationComplete + usleep(100*150); + int size = 0; + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + + // setup pdu session establishment request + uint16_t req_length = 6; + uint8_t *req_buffer = malloc(req_length); + pdu_session_establishment_request_msg pdu_session_establish; + pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE; + pdu_session_establish.pdusessionid = 10; + pdu_session_establish.pti = 0; + pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ; + pdu_session_establish.maxdatarate = 0xffff; + encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer); + + + + MM_msg *mm_msg; + nas_stream_cipher_t stream_cipher; + uint8_t mac[4]; + uint8_t nssai[]={1,1,2,3}; + uint8_t dnn[9]={0x8,0x69,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74}; + // set security protected header + nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX; + size += 7; + + mm_msg = &nas_msg.security_protected.plain.mm_msg; + + // set header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = FGS_UPLINK_NAS_TRANSPORT; + + // set uplink nas transport + mm_msg->uplink_nas_transport.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->uplink_nas_transport.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->uplink_nas_transport.messagetype = FGS_UPLINK_NAS_TRANSPORT; + size += 1; + + mm_msg->uplink_nas_transport.payloadcontainertype.iei = 0; + mm_msg->uplink_nas_transport.payloadcontainertype.type = 1; + size += 1; + mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length; + mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer; + size += (2+req_length); + mm_msg->uplink_nas_transport.pdusessionid = 10; + mm_msg->uplink_nas_transport.requesttype = 1; + size += 3; + mm_msg->uplink_nas_transport.snssai.length = 4; + mm_msg->uplink_nas_transport.snssai.value = nssai; + size += (1+1+4); + mm_msg->uplink_nas_transport.dnn.length = 9; + mm_msg->uplink_nas_transport.dnn.value = dnn; + size += (1+1+9); + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size); + + initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); + + stream_cipher.key = knas_int.value; + stream_cipher.key_length = 16; + stream_cipher.count = 0; + stream_cipher.bearer = 1; + stream_cipher.direction = 0; + stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6); + /* length in bits */ + stream_cipher.blength = (initialNasMsg->length - 6) << 3; + + // only for Type of integrity protection algorithm: 128-5G-IA2 (2) + nas_stream_encrypt_eia2( + &stream_cipher, + mac); + + printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); + for(int i = 0; i < 4; i++){ + initialNasMsg->data[2+i] = mac[i]; + } +} diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h new file mode 100644 index 0000000000..fef4671f43 --- /dev/null +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -0,0 +1,127 @@ +/* + * 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_nas_msg_sim.h + * \brief simulator for nr nas message + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com + * \date 2020 + * \version 0.1 + */ + + + +#ifndef __NR_NAS_MSG_SIM_H__ +#define __NR_NAS_MSG_SIM_H__ + +#include "RegistrationRequest.h" +#include "FGSIdentityResponse.h" +#include "FGSAuthenticationResponse.h" +#include "FGSNASSecurityModeComplete.h" +#include "RegistrationComplete.h" +#include "as_message.h" +#include "FGSUplinkNasTransport.h" + +#define PLAIN_5GS_MSG 0b0000 +#define INTEGRITY_PROTECTED 0b0001 +#define INTEGRITY_PROTECTED_AND_CIPHERED 0b0010 +#define INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX 0b0011 // only for SECURITY MODE COMMAND +#define INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX 0b0100 // only for SECURITY MODE COMPLETE + +#define REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */ +#define REGISTRATION_ACCEPT 0b01000010 /* 66 = 0x42 */ +#define REGISTRATION_COMPLETE 0b01000011 /* 67 = 0x43 */ +#define FGS_AUTHENTICATION_REQUEST 0b01010110 /* 86 = 0x56 */ +#define FGS_AUTHENTICATION_RESPONSE 0b01010111 /* 87 = 0x57 */ +#define FGS_IDENTITY_REQUEST 0b01011011 /* 91 = 0x5b */ +#define FGS_IDENTITY_RESPONSE 0b01011100 /* 92 = 0x5c */ +#define FGS_SECURITY_MODE_COMMAND 0b01011101 /* 93 = 0x5d */ +#define FGS_SECURITY_MODE_COMPLETE 0b01011110 /* 94 = 0x5e */ +#define FGS_UPLINK_NAS_TRANSPORT 0b01100111 /* 103= 0x67 */ + +// message type for 5GS session management +#define FGS_PDU_SESSION_ESTABLISHMENT_REQ 0b11000001 /* 193= 0xc1 */ + +#define INITIAL_REGISTRATION 0b001 + + +typedef enum fgs_protocol_discriminator_e { + /* Protocol discriminator identifier for 5GS Mobility Management */ + FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E, + + /* Protocol discriminator identifier for 5GS Session Management */ + FGS_SESSION_MANAGEMENT_MESSAGE = 0x2E, +} fgs_protocol_discriminator_t; + + +typedef struct { + uint8_t ex_protocol_discriminator; + uint8_t security_header_type; + uint8_t message_type; +} mm_msg_header_t; + +/* Structure of security protected header */ +typedef struct { + fgs_protocol_discriminator_t protocol_discriminator; + uint8_t security_header_type; + uint32_t message_authentication_code; + uint8_t sequence_number; +} fgs_nas_message_security_header_t; + +typedef union { + mm_msg_header_t header; + registration_request_msg registration_request; + fgs_identiy_response_msg fgs_identity_response; + fgs_authentication_response_msg fgs_auth_response; + fgs_security_mode_complete_msg fgs_security_mode_complete; + registration_complete_msg registration_complete; + fgs_uplink_nas_transport_msg uplink_nas_transport; +} MM_msg; + + + +typedef struct { + MM_msg mm_msg; /* 5GS Mobility Management messages */ +} fgs_nas_message_plain_t; + +typedef struct { + fgs_nas_message_security_header_t header; + fgs_nas_message_plain_t plain; +} fgs_nas_message_security_protected_t; + + +typedef union { + fgs_nas_message_security_header_t header; + fgs_nas_message_security_protected_t security_protected; + fgs_nas_message_plain_t plain; +} fgs_nas_message_t; + +void generateRegistrationRequest(as_nas_info_t *initialNasMsg); +void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype); +void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf); +void generateSecurityModeComplete(as_nas_info_t *initialNasMsg); +void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer); +void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg); + +#endif /* __NR_NAS_MSG_SIM_H__*/ + + + diff --git a/openair3/NAS/NR_UE/ue_process_nas.c b/openair3/NAS/NR_UE/ue_process_nas.c new file mode 100644 index 0000000000..a89a07218e --- /dev/null +++ b/openair3/NAS/NR_UE/ue_process_nas.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 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#include +#include + + +void SGSabortNet(void *msg, nr_user_nas_t *UE) { +} + +void ue_nas_schedule(void) { +} + +/* + *Message reception + */ + +void SGSauthenticationReq(void *msg, nr_user_nas_t *UE) { + authenticationrequestHeader_t *amsg=(authenticationrequestHeader_t *) msg; + arrayCpy(UE->uicc->rand,amsg->RAND); + arrayCpy(UE->uicc->autn,amsg->AUTN); + // AUTHENTICATION REQUEST message that contains a valid ngKSI, SQN and MAC is received + // TBD verify ngKSI (we set it as '2', see gNB code) + // SQN and MAC are tested in auth resp processing + ue_nas_schedule(); +} + +void SGSidentityReq(void *msg, nr_user_nas_t *UE) { + Identityrequest_t *idmsg=(Identityrequest_t *) msg; + + if (idmsg->it == SUCI ) { + LOG_I(NAS,"Received Identity request, scheduling answer\n"); + ue_nas_schedule(); + } else + LOG_E(NAS,"Not developped: identity request for %d\n", idmsg->it); +} + +void SGSsecurityModeCommand(void *msg, nr_user_nas_t *UE) { +} + + +void UEprocessNAS(void *msg,nr_user_nas_t *UE) { + SGScommonHeader_t *header=(SGScommonHeader_t *) msg; + + if ( header->sh > 4 ) + SGSabortNet(msg, UE); + else { + switch (header->epd) { + case SGSmobilitymanagementmessages: + LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt)); + + switch (header->mt) { + case Authenticationrequest: + SGSauthenticationReq(msg, UE); + break; + + case Identityrequest: + SGSidentityReq(msg, UE); + break; + + case Securitymodecommand: + SGSsecurityModeCommand(msg, UE); + break; + + default: + SGSabortNet(msg, UE); + } + + break; + + case SGSsessionmanagementmessages: + SGSabortNet(msg, UE); + break; + + default: + SGSabortNet(msg, UE); + } + } +} + +/* + * Messages emission + */ + +int identityResponse(void **msg, nr_user_nas_t *UE) { + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc("uicc"); + + // TS 24.501 9.11.3.4 + int imsiL=strlen(UE->uicc->imsiStr); + int msinL=imsiL-3-UE->uicc->nmc_size; + int respSize=sizeof(IdentityresponseIMSI_t) + (msinL+1)/2; + IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *) calloc(respSize,1); + resp->common.epd=SGSmobilitymanagementmessages; + resp->common.sh=0; + resp->common.mt=Identityresponse; + resp->common.len=htons(respSize-sizeof(Identityresponse_t)); + resp->mi=SUCI; + resp->mcc1=UE->uicc->imsiStr[0]-'0'; + resp->mcc2=UE->uicc->imsiStr[1]-'0'; + resp->mcc3=UE->uicc->imsiStr[2]-'0'; + resp->mnc1=UE->uicc->imsiStr[3]-'0'; + resp->mnc2=UE->uicc->imsiStr[4]-'0'; + resp->mnc3=UE->uicc->nmc_size==2? 0xF : UE->uicc->imsiStr[3]-'0'; + // TBD: routing to fill (FF ?) + char *out=(char *)(resp+1); + char *ptr=UE->uicc->imsiStr + 3 + UE->uicc->nmc_size; + + while ( ptr < UE->uicc->imsiStr+strlen(UE->uicc->imsiStr) ) { + *out=((*(ptr+1)-'0')<<4) | (*(ptr) -'0'); + out++; + ptr+=2; + } + + if (msinL%2 == 1) + *out=((*(ptr-1)-'0')) | 0xF0; + + *msg=resp; + return respSize; +} + +int authenticationResponse(void **msg,nr_user_nas_t *UE) { + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc("uicc"); + + myCalloc(resp, authenticationresponse_t); + resp->epd=SGSmobilitymanagementmessages; + resp->sh=0; + resp->mt=Authenticationresponse; + resp->iei=IEI_AuthenticationResponse; + resp->RESlen=sizeof(resp->RES); // always 16 see TS 24.501 Table 8.2.2.1.1 + // Verify the AUTN + // a full implementation need to test several SQN + // as the last 5bits can be any value + // and the value can also be greater and accepted (if it is in the accepted window) + uint8_t AUTN[16]; + uicc_milenage_generate(AUTN, UE->uicc); + + if ( memcmp(UE->uicc->autn, AUTN, sizeof(AUTN)) == 0 ) { + // prepare and send good answer + resToresStar(resp->RES,UE->uicc); + } else { + // prepare and send autn is not compatible with our data + abort(); + } + + *msg=resp; + return sizeof(authenticationresponse_t); +} + +int securityModeComplete(void **msg, nr_user_nas_t *UE) { + return -1; +} + +int registrationComplete(void **msg, nr_user_nas_t *UE) { + return -1; +} diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index cd493dd09e..0c79fa3e3a 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -55,10 +55,6 @@ Description Defines functions used to handle EPS bearer contexts. #include #include #include -#ifdef UESIM_EXPANSION - #include "openairinterface5g_limits.h" - extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -200,7 +196,7 @@ int esm_ebr_context_create( char *tmp = NULL; char ipv4_addr[INET_ADDRSTRLEN]; //char ipv6_addr[INET6_ADDRSTRLEN]; - char *netmask = NULL; + int netmask = 32; char broadcast[INET_ADDRSTRLEN]; struct in_addr in_addr; char command_line[500]; @@ -227,7 +223,7 @@ int esm_ebr_context_create( strcpy(ipv4_addr, tmp); if (IN_CLASSA(ntohl(in_addr.s_addr))) { - netmask = "255.0.0.0"; + netmask = 8; in_addr.s_addr = pdn->ip_addr[0] << 24 | ((255 << 16) & 0x00FF0000) | ((255 << 8) & 0x0000FF00) | @@ -239,7 +235,7 @@ int esm_ebr_context_create( // in_addr.s_addr); strcpy(broadcast, tmp); } else if (IN_CLASSB(ntohl(in_addr.s_addr))) { - netmask = "255.255.0.0"; + netmask = 16; in_addr.s_addr = pdn->ip_addr[0] << 24 | ((pdn->ip_addr[1] << 16) & 0x00FF0000) | ((255 << 8) & 0x0000FF00) | @@ -251,7 +247,7 @@ int esm_ebr_context_create( // in_addr.s_addr); strcpy(broadcast, tmp); } else if (IN_CLASSC(ntohl(in_addr.s_addr))) { - netmask = "255.255.255.0"; + netmask = 24; in_addr.s_addr = pdn->ip_addr[0] << 24 | ((pdn->ip_addr[1] << 16) & 0x00FF0000) | ((pdn->ip_addr[2] << 8) & 0x0000FF00) | @@ -263,56 +259,23 @@ int esm_ebr_context_create( // in_addr.s_addr); strcpy(broadcast, tmp); } else { - netmask = "255.255.255.255"; + netmask = 32; strcpy(broadcast, ipv4_addr); } - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { - // this is for L2 FAPI simulator. - // change for multiple UE's like 256UEs. - // if it's made too many tables , OS may crush so we use one table. - if(PDCP_USE_NETLINK) { -#ifdef UESIM_EXPANSION - uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2; - res = sprintf(command_line, - "ifconfig %s%d %s netmask %s broadcast %s up && " - "ip rule add from %s/24 table %d && " - "ip rule add to %s/24 table %d && " - "ip route add default dev %s%d table %d", - UE_NAS_USE_TUN?"oaitun_ue":"oip", - inst_nic + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, 201, - ipv4_addr, 201, - UE_NAS_USE_TUN?"oaitun_ue":"oip", - inst_nic + 1, 201); - inst_pdcp_list[inst_nic] = ueid; -#else - res = sprintf(command_line, - "ifconfig %s%d %s netmask %s broadcast %s up && " - "ip rule add from %s/32 table %d && " - "ip rule add to %s/32 table %d && " - "ip route add default dev %s%d table %d", - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, ueid + 201, - ipv4_addr, ueid + 201, - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ueid + 201); -#endif - } // PDCP_USE_NETLINK - } else { - res = sprintf(command_line, - "ifconfig %s%d %s netmask %s broadcast %s up && " - "ip rule add from %s/32 table %d && " - "ip rule add to %s/32 table %d && " - "ip route add default dev %s%d table %d", - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ipv4_addr, netmask, broadcast, - ipv4_addr, ueid + 201, - ipv4_addr, ueid + 201, - UE_NAS_USE_TUN?"oaitun_ue":"oip", - ueid + 1, ueid + 201); - } + res = sprintf(command_line, + "ip address add %s/%d broadcast %s dev %s%d && " + "ip link set %s%d up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev %s%d table %d", + ipv4_addr, netmask, broadcast, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, + ipv4_addr, ueid + 10000, + ipv4_addr, ueid + 10000, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", + ueid + 1, ueid + 10000); if ( res<0 ) { LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); diff --git a/openair3/NAS/UE/nas_itti_messaging.c b/openair3/NAS/UE/nas_itti_messaging.c index 885ebbdd81..8016e0d791 100644 --- a/openair3/NAS/UE/nas_itti_messaging.c +++ b/openair3/NAS/UE/nas_itti_messaging.c @@ -102,7 +102,7 @@ extern unsigned char NB_eNB_INST; int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_KENB_REFRESH_REQ); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_KENB_REFRESH_REQ); memcpy(NAS_KENB_REFRESH_REQ(message_p).kenb, kenb, sizeof(NAS_KENB_REFRESH_REQ(message_p).kenb)); MSC_LOG_TX_MESSAGE( MSC_NAS_UE, @@ -130,7 +130,7 @@ int nas_itti_kenb_refresh_req(const Byte_t kenb[32], int user_id) { int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CELL_SELECTION_REQ); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_CELL_SELECTION_REQ); NAS_CELL_SELECTION_REQ(message_p).plmnID = plmnID; NAS_CELL_SELECTION_REQ(message_p).rat = rat; MSC_LOG_TX_MESSAGE( @@ -145,7 +145,7 @@ int nas_itti_cell_info_req(const plmn_t plmnID, const Byte_t rat, int user_id) { int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t s_tmsi, plmn_t plmnID, Byte_t *data, uint32_t length, int user_id) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_CONN_ESTABLI_REQ); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_CONN_ESTABLI_REQ); NAS_CONN_ESTABLI_REQ(message_p).cause = cause; NAS_CONN_ESTABLI_REQ(message_p).type = type; NAS_CONN_ESTABLI_REQ(message_p).s_tmsi = s_tmsi; @@ -165,7 +165,7 @@ int nas_itti_nas_establish_req(as_cause_t cause, as_call_type_t type, as_stmsi_t int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t length, int user_id) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_UPLINK_DATA_REQ); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_UPLINK_DATA_REQ); NAS_UPLINK_DATA_REQ(message_p).UEid = ue_id; NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = data; NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = length; @@ -174,7 +174,7 @@ int nas_itti_ul_data_req(const uint32_t ue_id, void *const data, const uint32_t int nas_itti_rab_establish_rsp(const as_stmsi_t s_tmsi, const as_rab_id_t rabID, const nas_error_code_t errCode, int user_id) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, NAS_RAB_ESTABLI_RSP); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_RAB_ESTABLI_RSP); NAS_RAB_ESTABLI_RSP(message_p).s_tmsi = s_tmsi; NAS_RAB_ESTABLI_RSP(message_p).rabID = rabID; NAS_RAB_ESTABLI_RSP(message_p).errCode = errCode; diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index d712a7b7f0..178f21a44a 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -136,7 +136,7 @@ void *nas_ue_task(void *args_p) for (instance = NB_eNB_INST; instance < (NB_eNB_INST + NB_UE_INST); instance++) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, DEACTIVATE_MESSAGE); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, DEACTIVATE_MESSAGE); itti_send_msg_to_task(TASK_L2L1, instance, message_p); } @@ -145,7 +145,7 @@ void *nas_ue_task(void *args_p) itti_receive_msg (TASK_NAS_UE, &msg_p); if (msg_p != NULL) { - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); Mod_id = instance - NB_eNB_INST; if (instance == INSTANCE_DEFAULT) { printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n", diff --git a/openair3/NAS/gNB/network_process_nas.c b/openair3/NAS/gNB/network_process_nas.c new file mode 100644 index 0000000000..ce8897730b --- /dev/null +++ b/openair3/NAS/gNB/network_process_nas.c @@ -0,0 +1,214 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Author and copyright: Laurent Thomas, open-cells.com + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#include + +void SGSabortUE(void *msg, NRUEcontext_t *UE) { +} +void nas_schedule(void) { +} +/* + *Message reception + */ + +void SGSregistrationReq(void *msg, NRUEcontext_t *UE) { +} + +void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE) { +} + +void SGSidentityResp(void *msg, NRUEcontext_t *UE) { + // use the UE SUPI to load the USIM + IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *)msg; + char configName[100]={0}; + char * ptr= stpcpy(configName,"uicc"); + *ptr++=resp->mcc1+'0'; + *ptr++=resp->mcc2+'0'; + *ptr++=resp->mcc3+'0'; + *ptr++=resp->mnc1+'0'; + *ptr++=resp->mnc2+'0'; + if ( resp->mnc3 != 0xF ) + *ptr++=resp->mnc3 +'0'; + int respSize=ntohs(resp->common.len); + int msinByteSize=respSize-sizeof(IdentityresponseIMSI_t); + uint8_t * msin=(uint8_t *) (resp+1); + for(int i=3 ; i> 4) ; + *ptr++=(msin[i] & 0xf) +'0'; + if (digit1 != 0xf) + *ptr++=digit1 +'0'; + } + *ptr=0; + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc(configName); + //We schedule Authentication request + nas_schedule(); +} + +void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) { + // Let's check the answer + authenticationresponse_t* resp=(authenticationresponse_t*) msg; + uint8_t resStarLocal[16]; + resToresStar(resStarLocal,UE->uicc); + if ( memcmp(resStarLocal, resp->RES, sizeof(resStarLocal)) == 0 ) { + LOG_I(NAS,"UE answer to authentication resquest is correct\n"); + // we will send securityModeCommand + nas_schedule(); + } else { + LOG_E(NAS,"UE authentication response not good\n"); + // To be implemented ? + } +} + +void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) { + +} + +void SGSregistrationComplete(void *msg, NRUEcontext_t *UE) { +} + +void processNAS(void *msg, NRUEcontext_t *UE) { + SGScommonHeader_t *header=(SGScommonHeader_t *) msg; + + if ( header->sh > 4 ) + SGSabortUE(msg, UE); + else { + switch (header->epd) { + case SGSmobilitymanagementmessages: + LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt)); + + switch (header->mt) { + case Registrationrequest: + SGSregistrationReq(msg, UE); + break; + + case DeregistrationrequestUEoriginating: + SGSderegistrationUEReq(msg, UE); + break; + + case Authenticationresponse: + SGSauthenticationResp(msg, UE); + break; + + case Identityresponse: + SGSidentityResp(msg, UE); + break; + + case Securitymodecomplete: + SGSsecurityModeComplete(msg, UE); + break; + + case Registrationcomplete: + SGSregistrationComplete(msg, UE); + break; + + default: + SGSabortUE(msg, UE); + } + + break; + + case SGSsessionmanagementmessages: + SGSabortUE(msg, UE); + break; + + default: + SGSabortUE(msg, UE); + } + } +} + +/* + * Messages emission + */ + +int identityRequest(void **msg, NRUEcontext_t *UE) { + myCalloc(req, Identityrequest_t); + req->epd=SGSmobilitymanagementmessages; + req->sh=0; + req->mt=Identityrequest; + req->it=SUCI; + *msg=req; + return sizeof(Identityrequest_t); +} + +int authenticationRequest(void **msg, NRUEcontext_t *UE) { + + myCalloc(req, authenticationrequestHeader_t); + req->epd=SGSmobilitymanagementmessages; + req->sh=0; + req->mt=Authenticationrequest; + // native security context => bit 4 to 0 + // probably from TS 33.501, table A-8.1 + // N-NAS-int-alg (Native NAS integrity) + /* + N-NAS-enc-alg 0x01 + N-NAS-int-alg 0x02 + N-RRC-enc-alg 0x03 + N-RRC-int-alg 0x04 + N-UP-enc-alg 0x05 + N-UP-int-alg 0x06 + */ + req->ngKSI=2; + // TS 33.501, Annex A.7.1: Initial set of security features defined for 5GS. + req->ABBALen=2; + req->ABBA=0; + //rand (TV) + req->ieiRAND=IEI_RAND; + FILE *h=fopen("/dev/random","r"); + + if ( sizeof(req->RAND) != fread(req->RAND,1,sizeof(req->RAND),h) ) + LOG_E(NAS, "can't read /dev/random\n"); + + fclose(h); + memcpy(UE->uicc->rand, req->RAND, sizeof(UE->uicc->rand)); + // challenge/AUTN (TLV) + req->ieiAUTN=IEI_AUTN; + req->AUTNlen=sizeof(req->AUTN); + uicc_milenage_generate( req->AUTN, UE->uicc); + // EAP message (TLV-E) + // not developped + *msg=req; + return sizeof(authenticationrequestHeader_t); +} + +int securityModeCommand(void **msg, NRUEcontext_t *UE) { + *msg=NULL; + myCalloc(req, securityModeCommand_t); + req->epd=SGSmobilitymanagementmessages; + req->sh=0; + req->mt=Securitymodecommand; + + // integrity algo from 5G-IA0 (null algo) to 5G-IA7 in first 4 bits + unsigned int ia=0; + // cyphering algo from 5G-EA0 (null algo) to 5G-IA7 in MSB 4 bits + unsigned int ea=0; + // trace from commercial: 5G-IA0 (0) 128-5G-IA2 (2) + req->selectedNASsecurityalgorithms= ea<<4 | ia; + + // KSI: N-NAS-int-alg 0x02 + req->ngKSI=2; + + *msg=req; + return 0; +} diff --git a/openair3/NGAP/MESSAGES/ASN1/ASN1_files/ngap-15.8.0.asn1 b/openair3/NGAP/MESSAGES/ASN1/ASN1_files/ngap-15.8.0.asn1 new file mode 100644 index 0000000000..b808ed3ada --- /dev/null +++ b/openair3/NGAP/MESSAGES/ASN1/ASN1_files/ngap-15.8.0.asn1 @@ -0,0 +1,6886 @@ +-- ASN1START +-- ************************************************************** +-- +-- Elementary Procedure definitions +-- +-- ************************************************************** + +NGAP-PDU-Descriptions { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-PDU-Descriptions (0)} + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + Criticality, + ProcedureCode +FROM NGAP-CommonDataTypes + + AMFConfigurationUpdate, + AMFConfigurationUpdateAcknowledge, + AMFConfigurationUpdateFailure, + AMFStatusIndication, + CellTrafficTrace, + DeactivateTrace, + DownlinkNASTransport, + DownlinkNonUEAssociatedNRPPaTransport, + DownlinkRANConfigurationTransfer, + DownlinkRANStatusTransfer, + DownlinkUEAssociatedNRPPaTransport, + ErrorIndication, + HandoverCancel, + HandoverCancelAcknowledge, + HandoverCommand, + HandoverFailure, + HandoverNotify, + HandoverPreparationFailure, + HandoverRequest, + HandoverRequestAcknowledge, + HandoverRequired, + InitialContextSetupFailure, + InitialContextSetupRequest, + InitialContextSetupResponse, + InitialUEMessage, + LocationReport, + LocationReportingControl, + LocationReportingFailureIndication, + NASNonDeliveryIndication, + NGReset, + NGResetAcknowledge, + NGSetupFailure, + NGSetupRequest, + NGSetupResponse, + OverloadStart, + OverloadStop, + Paging, + PathSwitchRequest, + PathSwitchRequestAcknowledge, + PathSwitchRequestFailure, + PDUSessionResourceModifyConfirm, + PDUSessionResourceModifyIndication, + PDUSessionResourceModifyRequest, + PDUSessionResourceModifyResponse, + PDUSessionResourceNotify, + PDUSessionResourceReleaseCommand, + PDUSessionResourceReleaseResponse, + PDUSessionResourceSetupRequest, + PDUSessionResourceSetupResponse, + PrivateMessage, + PWSCancelRequest, + PWSCancelResponse, + PWSFailureIndication, + PWSRestartIndication, + RANConfigurationUpdate, + RANConfigurationUpdateAcknowledge, + RANConfigurationUpdateFailure, + RerouteNASRequest, + RRCInactiveTransitionReport, + SecondaryRATDataUsageReport, + TraceFailureIndication, + TraceStart, + UEContextModificationFailure, + UEContextModificationRequest, + UEContextModificationResponse, + UEContextReleaseCommand, + UEContextReleaseComplete, + UEContextReleaseRequest, + UERadioCapabilityCheckRequest, + UERadioCapabilityCheckResponse, + UERadioCapabilityInfoIndication, + UETNLABindingReleaseRequest, + UplinkNASTransport, + UplinkNonUEAssociatedNRPPaTransport, + UplinkRANConfigurationTransfer, + UplinkRANStatusTransfer, + UplinkUEAssociatedNRPPaTransport, + WriteReplaceWarningRequest, + WriteReplaceWarningResponse +FROM NGAP-PDU-Contents + + id-AMFConfigurationUpdate, + id-AMFStatusIndication, + id-CellTrafficTrace, + id-DeactivateTrace, + id-DownlinkNASTransport, + id-DownlinkNonUEAssociatedNRPPaTransport, + id-DownlinkRANConfigurationTransfer, + id-DownlinkRANStatusTransfer, + id-DownlinkUEAssociatedNRPPaTransport, + id-ErrorIndication, + id-HandoverCancel, + id-HandoverNotification, + id-HandoverPreparation, + id-HandoverResourceAllocation, + id-InitialContextSetup, + id-InitialUEMessage, + id-LocationReport, + id-LocationReportingControl, + id-LocationReportingFailureIndication, + id-NASNonDeliveryIndication, + id-NGReset, + id-NGSetup, + id-OverloadStart, + id-OverloadStop, + id-Paging, + id-PathSwitchRequest, + id-PDUSessionResourceModify, + id-PDUSessionResourceModifyIndication, + id-PDUSessionResourceNotify, + id-PDUSessionResourceRelease, + id-PDUSessionResourceSetup, + id-PrivateMessage, + id-PWSCancel, + id-PWSFailureIndication, + id-PWSRestartIndication, + id-RANConfigurationUpdate, + id-RerouteNASRequest, + id-RRCInactiveTransitionReport, + id-SecondaryRATDataUsageReport, + id-TraceFailureIndication, + id-TraceStart, + id-UEContextModification, + id-UEContextRelease, + id-UEContextReleaseRequest, + id-UERadioCapabilityCheck, + id-UERadioCapabilityInfoIndication, + id-UETNLABindingRelease, + id-UplinkNASTransport, + id-UplinkNonUEAssociatedNRPPaTransport, + id-UplinkRANConfigurationTransfer, + id-UplinkRANStatusTransfer, + id-UplinkUEAssociatedNRPPaTransport, + id-WriteReplaceWarning +FROM NGAP-Constants; + +-- ************************************************************** +-- +-- Interface Elementary Procedure Class +-- +-- ************************************************************** + +NGAP-ELEMENTARY-PROCEDURE ::= CLASS { + &InitiatingMessage , + &SuccessfulOutcome OPTIONAL, + &UnsuccessfulOutcome OPTIONAL, + &procedureCode ProcedureCode UNIQUE, + &criticality Criticality DEFAULT ignore +} + +WITH SYNTAX { + INITIATING MESSAGE &InitiatingMessage + [SUCCESSFUL OUTCOME &SuccessfulOutcome] + [UNSUCCESSFUL OUTCOME &UnsuccessfulOutcome] + PROCEDURE CODE &procedureCode + [CRITICALITY &criticality] +} + +-- ************************************************************** +-- +-- Interface PDU Definition +-- +-- ************************************************************** + +NGAP-PDU ::= CHOICE { + initiatingMessage InitiatingMessage, + successfulOutcome SuccessfulOutcome, + unsuccessfulOutcome UnsuccessfulOutcome, + ... +} + +InitiatingMessage ::= SEQUENCE { + procedureCode NGAP-ELEMENTARY-PROCEDURE.&procedureCode ({NGAP-ELEMENTARY-PROCEDURES}), + criticality NGAP-ELEMENTARY-PROCEDURE.&criticality ({NGAP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value NGAP-ELEMENTARY-PROCEDURE.&InitiatingMessage ({NGAP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +SuccessfulOutcome ::= SEQUENCE { + procedureCode NGAP-ELEMENTARY-PROCEDURE.&procedureCode ({NGAP-ELEMENTARY-PROCEDURES}), + criticality NGAP-ELEMENTARY-PROCEDURE.&criticality ({NGAP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value NGAP-ELEMENTARY-PROCEDURE.&SuccessfulOutcome ({NGAP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +UnsuccessfulOutcome ::= SEQUENCE { + procedureCode NGAP-ELEMENTARY-PROCEDURE.&procedureCode ({NGAP-ELEMENTARY-PROCEDURES}), + criticality NGAP-ELEMENTARY-PROCEDURE.&criticality ({NGAP-ELEMENTARY-PROCEDURES}{@procedureCode}), + value NGAP-ELEMENTARY-PROCEDURE.&UnsuccessfulOutcome ({NGAP-ELEMENTARY-PROCEDURES}{@procedureCode}) +} + +-- ************************************************************** +-- +-- Interface Elementary Procedure List +-- +-- ************************************************************** + +NGAP-ELEMENTARY-PROCEDURES NGAP-ELEMENTARY-PROCEDURE ::= { + NGAP-ELEMENTARY-PROCEDURES-CLASS-1 | + NGAP-ELEMENTARY-PROCEDURES-CLASS-2, + ... +} + +NGAP-ELEMENTARY-PROCEDURES-CLASS-1 NGAP-ELEMENTARY-PROCEDURE ::= { + aMFConfigurationUpdate | + handoverCancel | + handoverPreparation | + handoverResourceAllocation | + initialContextSetup | + nGReset | + nGSetup | + pathSwitchRequest | + pDUSessionResourceModify | + pDUSessionResourceModifyIndication | + pDUSessionResourceRelease | + pDUSessionResourceSetup | + pWSCancel | + rANConfigurationUpdate | + uEContextModification | + uEContextRelease | + uERadioCapabilityCheck | + writeReplaceWarning +} + +NGAP-ELEMENTARY-PROCEDURES-CLASS-2 NGAP-ELEMENTARY-PROCEDURE ::= { + aMFStatusIndication | + cellTrafficTrace | + deactivateTrace | + downlinkNASTransport | + downlinkNonUEAssociatedNRPPaTransport | + downlinkRANConfigurationTransfer | + downlinkRANStatusTransfer | + downlinkUEAssociatedNRPPaTransport | + errorIndication | + handoverNotification | + initialUEMessage | + locationReport | + locationReportingControl | + locationReportingFailureIndication | + nASNonDeliveryIndication | + overloadStart | + overloadStop | + paging | + pDUSessionResourceNotify | + privateMessage | + pWSFailureIndication | + pWSRestartIndication | + rerouteNASRequest | + rRCInactiveTransitionReport | + secondaryRATDataUsageReport | + traceFailureIndication | + traceStart | + uEContextReleaseRequest | + uERadioCapabilityInfoIndication | + uETNLABindingRelease | + uplinkNASTransport | + uplinkNonUEAssociatedNRPPaTransport | + uplinkRANConfigurationTransfer | + uplinkRANStatusTransfer | + uplinkUEAssociatedNRPPaTransport +} + +-- ************************************************************** +-- +-- Interface Elementary Procedures +-- +-- ************************************************************** + +aMFConfigurationUpdate NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE AMFConfigurationUpdate + SUCCESSFUL OUTCOME AMFConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME AMFConfigurationUpdateFailure + PROCEDURE CODE id-AMFConfigurationUpdate + CRITICALITY reject +} + +aMFStatusIndication NGAP-ELEMENTARY-PROCEDURE ::={ + INITIATING MESSAGE AMFStatusIndication + PROCEDURE CODE id-AMFStatusIndication + CRITICALITY ignore +} + +cellTrafficTrace NGAP-ELEMENTARY-PROCEDURE ::={ + INITIATING MESSAGE CellTrafficTrace + PROCEDURE CODE id-CellTrafficTrace + CRITICALITY ignore +} + +deactivateTrace NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DeactivateTrace + PROCEDURE CODE id-DeactivateTrace + CRITICALITY ignore +} + +downlinkNASTransport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DownlinkNASTransport + PROCEDURE CODE id-DownlinkNASTransport + CRITICALITY ignore +} + +downlinkNonUEAssociatedNRPPaTransport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DownlinkNonUEAssociatedNRPPaTransport + PROCEDURE CODE id-DownlinkNonUEAssociatedNRPPaTransport + CRITICALITY ignore +} + +downlinkRANConfigurationTransfer NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DownlinkRANConfigurationTransfer + PROCEDURE CODE id-DownlinkRANConfigurationTransfer + CRITICALITY ignore +} + +downlinkRANStatusTransfer NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DownlinkRANStatusTransfer + PROCEDURE CODE id-DownlinkRANStatusTransfer + CRITICALITY ignore +} + +downlinkUEAssociatedNRPPaTransport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE DownlinkUEAssociatedNRPPaTransport + PROCEDURE CODE id-DownlinkUEAssociatedNRPPaTransport + CRITICALITY ignore +} + +errorIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE ErrorIndication + PROCEDURE CODE id-ErrorIndication + CRITICALITY ignore +} + +handoverCancel NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE HandoverCancel + SUCCESSFUL OUTCOME HandoverCancelAcknowledge + PROCEDURE CODE id-HandoverCancel + CRITICALITY reject +} + +handoverNotification NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE HandoverNotify + PROCEDURE CODE id-HandoverNotification + CRITICALITY ignore +} + +handoverPreparation NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE HandoverRequired + SUCCESSFUL OUTCOME HandoverCommand + UNSUCCESSFUL OUTCOME HandoverPreparationFailure + PROCEDURE CODE id-HandoverPreparation + CRITICALITY reject +} + +handoverResourceAllocation NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE HandoverRequest + SUCCESSFUL OUTCOME HandoverRequestAcknowledge + UNSUCCESSFUL OUTCOME HandoverFailure + PROCEDURE CODE id-HandoverResourceAllocation + CRITICALITY reject +} + +initialContextSetup NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE InitialContextSetupRequest + SUCCESSFUL OUTCOME InitialContextSetupResponse + UNSUCCESSFUL OUTCOME InitialContextSetupFailure + PROCEDURE CODE id-InitialContextSetup + CRITICALITY reject +} + +initialUEMessage NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE InitialUEMessage + PROCEDURE CODE id-InitialUEMessage + CRITICALITY ignore +} + +locationReport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE LocationReport + PROCEDURE CODE id-LocationReport + CRITICALITY ignore +} + +locationReportingControl NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE LocationReportingControl + PROCEDURE CODE id-LocationReportingControl + CRITICALITY ignore +} + +locationReportingFailureIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE LocationReportingFailureIndication + PROCEDURE CODE id-LocationReportingFailureIndication + CRITICALITY ignore +} + +nASNonDeliveryIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE NASNonDeliveryIndication + PROCEDURE CODE id-NASNonDeliveryIndication + CRITICALITY ignore +} + +nGReset NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE NGReset + SUCCESSFUL OUTCOME NGResetAcknowledge + PROCEDURE CODE id-NGReset + CRITICALITY reject +} + +nGSetup NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE NGSetupRequest + SUCCESSFUL OUTCOME NGSetupResponse + UNSUCCESSFUL OUTCOME NGSetupFailure + PROCEDURE CODE id-NGSetup + CRITICALITY reject +} + +overloadStart NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE OverloadStart + PROCEDURE CODE id-OverloadStart + CRITICALITY ignore +} + +overloadStop NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE OverloadStop + PROCEDURE CODE id-OverloadStop + CRITICALITY reject +} + +paging NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE Paging + PROCEDURE CODE id-Paging + CRITICALITY ignore +} + +pathSwitchRequest NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PathSwitchRequest + SUCCESSFUL OUTCOME PathSwitchRequestAcknowledge + UNSUCCESSFUL OUTCOME PathSwitchRequestFailure + PROCEDURE CODE id-PathSwitchRequest + CRITICALITY reject +} + +pDUSessionResourceModify NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PDUSessionResourceModifyRequest + SUCCESSFUL OUTCOME PDUSessionResourceModifyResponse + PROCEDURE CODE id-PDUSessionResourceModify + CRITICALITY reject +} + +pDUSessionResourceModifyIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PDUSessionResourceModifyIndication + SUCCESSFUL OUTCOME PDUSessionResourceModifyConfirm + PROCEDURE CODE id-PDUSessionResourceModifyIndication + CRITICALITY reject +} + +pDUSessionResourceNotify NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PDUSessionResourceNotify + PROCEDURE CODE id-PDUSessionResourceNotify + CRITICALITY ignore +} + +pDUSessionResourceRelease NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PDUSessionResourceReleaseCommand + SUCCESSFUL OUTCOME PDUSessionResourceReleaseResponse + PROCEDURE CODE id-PDUSessionResourceRelease + CRITICALITY reject +} + +pDUSessionResourceSetup NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PDUSessionResourceSetupRequest + SUCCESSFUL OUTCOME PDUSessionResourceSetupResponse + PROCEDURE CODE id-PDUSessionResourceSetup + CRITICALITY reject +} + +privateMessage NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PrivateMessage + PROCEDURE CODE id-PrivateMessage + CRITICALITY ignore +} + +pWSCancel NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PWSCancelRequest + SUCCESSFUL OUTCOME PWSCancelResponse + PROCEDURE CODE id-PWSCancel + CRITICALITY reject +} + +pWSFailureIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PWSFailureIndication + PROCEDURE CODE id-PWSFailureIndication + CRITICALITY ignore +} + +pWSRestartIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE PWSRestartIndication + PROCEDURE CODE id-PWSRestartIndication + CRITICALITY ignore +} + +rANConfigurationUpdate NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE RANConfigurationUpdate + SUCCESSFUL OUTCOME RANConfigurationUpdateAcknowledge + UNSUCCESSFUL OUTCOME RANConfigurationUpdateFailure + PROCEDURE CODE id-RANConfigurationUpdate + CRITICALITY reject +} + +rerouteNASRequest NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE RerouteNASRequest + PROCEDURE CODE id-RerouteNASRequest + CRITICALITY reject +} + +rRCInactiveTransitionReport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE RRCInactiveTransitionReport + PROCEDURE CODE id-RRCInactiveTransitionReport + CRITICALITY ignore +} + +secondaryRATDataUsageReport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE SecondaryRATDataUsageReport + PROCEDURE CODE id-SecondaryRATDataUsageReport + CRITICALITY ignore +} + +traceFailureIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE TraceFailureIndication + PROCEDURE CODE id-TraceFailureIndication + CRITICALITY ignore +} + +traceStart NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE TraceStart + PROCEDURE CODE id-TraceStart + CRITICALITY ignore +} + +uEContextModification NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextModificationRequest + SUCCESSFUL OUTCOME UEContextModificationResponse + UNSUCCESSFUL OUTCOME UEContextModificationFailure + PROCEDURE CODE id-UEContextModification + CRITICALITY reject +} + +uEContextRelease NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextReleaseCommand + SUCCESSFUL OUTCOME UEContextReleaseComplete + PROCEDURE CODE id-UEContextRelease + CRITICALITY reject +} + +uEContextReleaseRequest NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UEContextReleaseRequest + PROCEDURE CODE id-UEContextReleaseRequest + CRITICALITY ignore +} + +uERadioCapabilityCheck NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UERadioCapabilityCheckRequest + SUCCESSFUL OUTCOME UERadioCapabilityCheckResponse + PROCEDURE CODE id-UERadioCapabilityCheck + CRITICALITY reject +} + +uERadioCapabilityInfoIndication NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UERadioCapabilityInfoIndication + PROCEDURE CODE id-UERadioCapabilityInfoIndication + CRITICALITY ignore +} + +uETNLABindingRelease NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UETNLABindingReleaseRequest + PROCEDURE CODE id-UETNLABindingRelease + CRITICALITY ignore +} + +uplinkNASTransport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UplinkNASTransport + PROCEDURE CODE id-UplinkNASTransport + CRITICALITY ignore +} + +uplinkNonUEAssociatedNRPPaTransport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UplinkNonUEAssociatedNRPPaTransport + PROCEDURE CODE id-UplinkNonUEAssociatedNRPPaTransport + CRITICALITY ignore +} + +uplinkRANConfigurationTransfer NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UplinkRANConfigurationTransfer + PROCEDURE CODE id-UplinkRANConfigurationTransfer + CRITICALITY ignore +} + +uplinkRANStatusTransfer NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UplinkRANStatusTransfer + PROCEDURE CODE id-UplinkRANStatusTransfer + CRITICALITY ignore +} + +uplinkUEAssociatedNRPPaTransport NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE UplinkUEAssociatedNRPPaTransport + PROCEDURE CODE id-UplinkUEAssociatedNRPPaTransport + CRITICALITY ignore +} + +writeReplaceWarning NGAP-ELEMENTARY-PROCEDURE ::= { + INITIATING MESSAGE WriteReplaceWarningRequest + SUCCESSFUL OUTCOME WriteReplaceWarningResponse + PROCEDURE CODE id-WriteReplaceWarning + CRITICALITY reject +} + +END +-- ASN1STOP + +-- ASN1START +-- ************************************************************** +-- +-- PDU definitions for NGAP. +-- +-- ************************************************************** + +NGAP-PDU-Contents { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-PDU-Contents (1) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + AllowedNSSAI, + AMFName, + AMFSetID, + AMF-TNLAssociationSetupList, + AMF-TNLAssociationToAddList, + AMF-TNLAssociationToRemoveList, + AMF-TNLAssociationToUpdateList, + AMF-UE-NGAP-ID, + AssistanceDataForPaging, + BroadcastCancelledAreaList, + BroadcastCompletedAreaList, + CancelAllWarningMessages, + Cause, + CellIDListForRestart, + CNAssistedRANTuning, + ConcurrentWarningMessageInd, + CoreNetworkAssistanceInformationForInactive, + CPTransportLayerInformation, + CriticalityDiagnostics, + DataCodingScheme, + DirectForwardingPathAvailability, + EmergencyAreaIDListForRestart, + EmergencyFallbackIndicator, + EN-DCSONConfigurationTransfer, + EUTRA-CGI, + FiveG-S-TMSI, + GlobalRANNodeID, + GUAMI, + HandoverFlag, + HandoverType, + IMSVoiceSupportIndicator, + IndexToRFSP, + InfoOnRecommendedCellsAndRANNodesForPaging, + LocationReportingRequestType, + MaskedIMEISV, + MessageIdentifier, + MobilityRestrictionList, + NAS-PDU, + NASSecurityParametersFromNGRAN, + NewSecurityContextInd, + NGRAN-CGI, + NGRAN-TNLAssociationToRemoveList, + NGRANTraceID, + NR-CGI, + NRPPa-PDU, + NumberOfBroadcastsRequested, + OverloadResponse, + OverloadStartNSSAIList, + PagingDRX, + PagingOrigin, + PagingPriority, + PDUSessionAggregateMaximumBitRate, + PDUSessionResourceAdmittedList, + PDUSessionResourceFailedToModifyListModCfm, + PDUSessionResourceFailedToModifyListModRes, + PDUSessionResourceFailedToSetupListCxtFail, + PDUSessionResourceFailedToSetupListCxtRes, + PDUSessionResourceFailedToSetupListHOAck, + PDUSessionResourceFailedToSetupListPSReq, + PDUSessionResourceFailedToSetupListSURes, + PDUSessionResourceHandoverList, + PDUSessionResourceListCxtRelCpl, + PDUSessionResourceListCxtRelReq, + PDUSessionResourceListHORqd, + PDUSessionResourceModifyListModCfm, + PDUSessionResourceModifyListModInd, + PDUSessionResourceModifyListModReq, + PDUSessionResourceModifyListModRes, + PDUSessionResourceNotifyList, + PDUSessionResourceReleasedListNot, + PDUSessionResourceReleasedListPSAck, + PDUSessionResourceReleasedListPSFail, + PDUSessionResourceReleasedListRelRes, + PDUSessionResourceSecondaryRATUsageList, + PDUSessionResourceSetupListCxtReq, + PDUSessionResourceSetupListCxtRes, + PDUSessionResourceSetupListHOReq, + PDUSessionResourceSetupListSUReq, + PDUSessionResourceSetupListSURes, + PDUSessionResourceSwitchedList, + PDUSessionResourceToBeSwitchedDLList, + PDUSessionResourceToReleaseListHOCmd, + PDUSessionResourceToReleaseListRelCmd, + PLMNIdentity, + PLMNSupportList, + PWSFailedCellIDList, + RANNodeName, + RANPagingPriority, + RANStatusTransfer-TransparentContainer, + RAN-UE-NGAP-ID, + RedirectionVoiceFallback, + RelativeAMFCapacity, + RepetitionPeriod, + ResetType, + RoutingID, + RRCEstablishmentCause, + RRCInactiveTransitionReportRequest, + RRCState, + SecurityContext, + SecurityKey, + SerialNumber, + ServedGUAMIList, + SliceSupportList, + S-NSSAI, + SONConfigurationTransfer, + SourceToTarget-TransparentContainer, + SourceToTarget-AMFInformationReroute, + SupportedTAList, + TAIListForPaging, + TAIListForRestart, + TargetID, + TargetToSource-TransparentContainer, + TimeToWait, + TNLAssociationList, + TraceActivation, + TrafficLoadReductionIndication, + TransportLayerAddress, + UEAggregateMaximumBitRate, + UE-associatedLogicalNG-connectionList, + UEContextRequest, + UE-NGAP-IDs, + UEPagingIdentity, + UEPresenceInAreaOfInterestList, + UERadioCapability, + UERadioCapabilityForPaging, + UERetentionInformation, + UESecurityCapabilities, + UnavailableGUAMIList, + UserLocationInformation, + WarningAreaCoordinates, + WarningAreaList, + WarningMessageContents, + WarningSecurityInfo, + WarningType + +FROM NGAP-IEs + + PrivateIE-Container{}, + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + ProtocolIE-ContainerList{}, + ProtocolIE-ContainerPair{}, + ProtocolIE-SingleContainer{}, + NGAP-PRIVATE-IES, + NGAP-PROTOCOL-EXTENSION, + NGAP-PROTOCOL-IES, + NGAP-PROTOCOL-IES-PAIR +FROM NGAP-Containers + + id-AllowedNSSAI, + id-AMFName, + id-AMFOverloadResponse, + id-AMFSetID, + id-AMF-TNLAssociationFailedToSetupList, + id-AMF-TNLAssociationSetupList, + id-AMF-TNLAssociationToAddList, + id-AMF-TNLAssociationToRemoveList, + id-AMF-TNLAssociationToUpdateList, + id-AMFTrafficLoadReductionIndication, + id-AMF-UE-NGAP-ID, + id-AssistanceDataForPaging, + id-BroadcastCancelledAreaList, + id-BroadcastCompletedAreaList, + id-CancelAllWarningMessages, + id-Cause, + id-CellIDListForRestart, + id-CNAssistedRANTuning, + id-ConcurrentWarningMessageInd, + id-CoreNetworkAssistanceInformationForInactive, + id-CriticalityDiagnostics, + id-DataCodingScheme, + id-DefaultPagingDRX, + id-DirectForwardingPathAvailability, + id-EmergencyAreaIDListForRestart, + id-EmergencyFallbackIndicator, + id-ENDC-SONConfigurationTransferDL, + id-ENDC-SONConfigurationTransferUL, + id-EUTRA-CGI, + id-FiveG-S-TMSI, + id-GlobalRANNodeID, + id-GUAMI, + id-HandoverFlag, + id-HandoverType, + id-IMSVoiceSupportIndicator, + id-IndexToRFSP, + id-InfoOnRecommendedCellsAndRANNodesForPaging, + id-LocationReportingRequestType, + id-MaskedIMEISV, + id-MessageIdentifier, + id-MobilityRestrictionList, + id-NAS-PDU, + id-NASC, + id-NASSecurityParametersFromNGRAN, + id-NewAMF-UE-NGAP-ID, + id-NewGUAMI, + id-NewSecurityContextInd, + id-NGAP-Message, + id-NGRAN-CGI, + id-NGRAN-TNLAssociationToRemoveList, + id-NGRANTraceID, + id-NR-CGI, + id-NRPPa-PDU, + id-NumberOfBroadcastsRequested, + id-OldAMF, + id-OverloadStartNSSAIList, + id-PagingDRX, + id-PagingOrigin, + id-PagingPriority, + id-PDUSessionResourceAdmittedList, + id-PDUSessionResourceFailedToModifyListModCfm, + id-PDUSessionResourceFailedToModifyListModRes, + id-PDUSessionResourceFailedToSetupListCxtFail, + id-PDUSessionResourceFailedToSetupListCxtRes, + id-PDUSessionResourceFailedToSetupListHOAck, + id-PDUSessionResourceFailedToSetupListPSReq, + id-PDUSessionResourceFailedToSetupListSURes, + id-PDUSessionResourceHandoverList, + id-PDUSessionResourceListCxtRelCpl, + id-PDUSessionResourceListCxtRelReq, + id-PDUSessionResourceListHORqd, + id-PDUSessionResourceModifyListModCfm, + id-PDUSessionResourceModifyListModInd, + id-PDUSessionResourceModifyListModReq, + id-PDUSessionResourceModifyListModRes, + id-PDUSessionResourceNotifyList, + id-PDUSessionResourceReleasedListNot, + id-PDUSessionResourceReleasedListPSAck, + id-PDUSessionResourceReleasedListPSFail, + id-PDUSessionResourceReleasedListRelRes, + id-PDUSessionResourceSecondaryRATUsageList, + id-PDUSessionResourceSetupListCxtReq, + id-PDUSessionResourceSetupListCxtRes, + id-PDUSessionResourceSetupListHOReq, + id-PDUSessionResourceSetupListSUReq, + id-PDUSessionResourceSetupListSURes, + id-PDUSessionResourceSwitchedList, + id-PDUSessionResourceToBeSwitchedDLList, + id-PDUSessionResourceToReleaseListHOCmd, + id-PDUSessionResourceToReleaseListRelCmd, + id-PLMNSupportList, + id-PWSFailedCellIDList, + id-RANNodeName, + id-RANPagingPriority, + id-RANStatusTransfer-TransparentContainer, + id-RAN-UE-NGAP-ID, + id-RedirectionVoiceFallback, + id-RelativeAMFCapacity, + id-RepetitionPeriod, + id-ResetType, + id-RoutingID, + id-RRCEstablishmentCause, + id-RRCInactiveTransitionReportRequest, + id-RRCState, + id-SecurityContext, + id-SecurityKey, + id-SelectedPLMNIdentity, + id-SerialNumber, + id-ServedGUAMIList, + id-SliceSupportList, + id-SONConfigurationTransferDL, + id-SONConfigurationTransferUL, + id-SourceAMF-UE-NGAP-ID, + id-SourceToTarget-TransparentContainer, + id-SourceToTarget-AMFInformationReroute, + id-SupportedTAList, + id-TAIListForPaging, + id-TAIListForRestart, + id-TargetID, + id-TargetToSource-TransparentContainer, + id-TimeToWait, + id-TraceActivation, + id-TraceCollectionEntityIPAddress, + id-UEAggregateMaximumBitRate, + id-UE-associatedLogicalNG-connectionList, + id-UEContextRequest, + id-UE-NGAP-IDs, + id-UEPagingIdentity, + id-UEPresenceInAreaOfInterestList, + id-UERadioCapability, + id-UERadioCapabilityForPaging, + id-UERetentionInformation, + id-UESecurityCapabilities, + id-UnavailableGUAMIList, + id-UserLocationInformation, + id-WarningAreaCoordinates, + id-WarningAreaList, + id-WarningMessageContents, + id-WarningSecurityInfo, + id-WarningType + +FROM NGAP-Constants; + +-- ************************************************************** +-- +-- PDU SESSION MANAGEMENT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PDU Session Resource Setup Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE SETUP REQUEST +-- +-- ************************************************************** + +PDUSessionResourceSetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceSetupRequestIEs} }, + ... +} + +PDUSessionResourceSetupRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RANPagingPriority CRITICALITY ignore TYPE RANPagingPriority PRESENCE optional }| + { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE optional }| + { ID id-PDUSessionResourceSetupListSUReq CRITICALITY reject TYPE PDUSessionResourceSetupListSUReq PRESENCE mandatory }| + { ID id-UEAggregateMaximumBitRate CRITICALITY ignore TYPE UEAggregateMaximumBitRate PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE SETUP RESPONSE +-- +-- ************************************************************** + +PDUSessionResourceSetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceSetupResponseIEs} }, + ... +} + +PDUSessionResourceSetupResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceSetupListSURes CRITICALITY ignore TYPE PDUSessionResourceSetupListSURes PRESENCE optional }| + { ID id-PDUSessionResourceFailedToSetupListSURes CRITICALITY ignore TYPE PDUSessionResourceFailedToSetupListSURes PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- PDU Session Resource Release Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE RELEASE COMMAND +-- +-- ************************************************************** + +PDUSessionResourceReleaseCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceReleaseCommandIEs} }, + ... +} + +PDUSessionResourceReleaseCommandIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RANPagingPriority CRITICALITY ignore TYPE RANPagingPriority PRESENCE optional }| + { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE optional }| + { ID id-PDUSessionResourceToReleaseListRelCmd CRITICALITY reject TYPE PDUSessionResourceToReleaseListRelCmd PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE RELEASE RESPONSE +-- +-- ************************************************************** + +PDUSessionResourceReleaseResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceReleaseResponseIEs} }, + ... +} + +PDUSessionResourceReleaseResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceReleasedListRelRes CRITICALITY ignore TYPE PDUSessionResourceReleasedListRelRes PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PDU Session Resource Modify Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE MODIFY REQUEST +-- +-- ************************************************************** + +PDUSessionResourceModifyRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceModifyRequestIEs} }, + ... +} + +PDUSessionResourceModifyRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RANPagingPriority CRITICALITY ignore TYPE RANPagingPriority PRESENCE optional }| + { ID id-PDUSessionResourceModifyListModReq CRITICALITY reject TYPE PDUSessionResourceModifyListModReq PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE MODIFY RESPONSE +-- +-- ************************************************************** + +PDUSessionResourceModifyResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceModifyResponseIEs} }, + ... +} + +PDUSessionResourceModifyResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceModifyListModRes CRITICALITY ignore TYPE PDUSessionResourceModifyListModRes PRESENCE optional }| + { ID id-PDUSessionResourceFailedToModifyListModRes CRITICALITY ignore TYPE PDUSessionResourceFailedToModifyListModRes PRESENCE optional }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- PDU Session Resource Notify Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE NOTIFY +-- +-- ************************************************************** + +PDUSessionResourceNotify ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceNotifyIEs} }, + ... +} + +PDUSessionResourceNotifyIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceNotifyList CRITICALITY reject TYPE PDUSessionResourceNotifyList PRESENCE optional }| + { ID id-PDUSessionResourceReleasedListNot CRITICALITY ignore TYPE PDUSessionResourceReleasedListNot PRESENCE optional }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- PDU Session Resource Modify Indication Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE MODIFY INDICATION +-- +-- ************************************************************** + +PDUSessionResourceModifyIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceModifyIndicationIEs} }, + ... +} + +PDUSessionResourceModifyIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceModifyListModInd CRITICALITY reject TYPE PDUSessionResourceModifyListModInd PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PDU SESSION RESOURCE MODIFY CONFIRM +-- +-- ************************************************************** + +PDUSessionResourceModifyConfirm ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceModifyConfirmIEs} }, + ... +} + +PDUSessionResourceModifyConfirmIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceModifyListModCfm CRITICALITY ignore TYPE PDUSessionResourceModifyListModCfm PRESENCE optional }| + { ID id-PDUSessionResourceFailedToModifyListModCfm CRITICALITY ignore TYPE PDUSessionResourceFailedToModifyListModCfm PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MANAGEMENT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Initial Context Setup Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- INITIAL CONTEXT SETUP REQUEST +-- +-- ************************************************************** + +InitialContextSetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {InitialContextSetupRequestIEs} }, + ... +} + +InitialContextSetupRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-OldAMF CRITICALITY reject TYPE AMFName PRESENCE optional }| + { ID id-UEAggregateMaximumBitRate CRITICALITY reject TYPE UEAggregateMaximumBitRate PRESENCE conditional }| + { ID id-CoreNetworkAssistanceInformationForInactive CRITICALITY ignore TYPE CoreNetworkAssistanceInformationForInactive PRESENCE optional }| + { ID id-GUAMI CRITICALITY reject TYPE GUAMI PRESENCE mandatory }| + { ID id-PDUSessionResourceSetupListCxtReq CRITICALITY reject TYPE PDUSessionResourceSetupListCxtReq PRESENCE optional }| + { ID id-AllowedNSSAI CRITICALITY reject TYPE AllowedNSSAI PRESENCE mandatory }| + { ID id-UESecurityCapabilities CRITICALITY reject TYPE UESecurityCapabilities PRESENCE mandatory }| + { ID id-SecurityKey CRITICALITY reject TYPE SecurityKey PRESENCE mandatory }| + { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE optional }| + { ID id-MobilityRestrictionList CRITICALITY ignore TYPE MobilityRestrictionList PRESENCE optional }| + { ID id-UERadioCapability CRITICALITY ignore TYPE UERadioCapability PRESENCE optional }| + { ID id-IndexToRFSP CRITICALITY ignore TYPE IndexToRFSP PRESENCE optional }| + { ID id-MaskedIMEISV CRITICALITY ignore TYPE MaskedIMEISV PRESENCE optional }| + { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE optional }| + { ID id-EmergencyFallbackIndicator CRITICALITY reject TYPE EmergencyFallbackIndicator PRESENCE optional }| + { ID id-RRCInactiveTransitionReportRequest CRITICALITY ignore TYPE RRCInactiveTransitionReportRequest PRESENCE optional }| + { ID id-UERadioCapabilityForPaging CRITICALITY ignore TYPE UERadioCapabilityForPaging PRESENCE optional }| + { ID id-RedirectionVoiceFallback CRITICALITY ignore TYPE RedirectionVoiceFallback PRESENCE optional }| + { ID id-LocationReportingRequestType CRITICALITY ignore TYPE LocationReportingRequestType PRESENCE optional }| + { ID id-CNAssistedRANTuning CRITICALITY ignore TYPE CNAssistedRANTuning PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- INITIAL CONTEXT SETUP RESPONSE +-- +-- ************************************************************** + +InitialContextSetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {InitialContextSetupResponseIEs} }, + ... +} + +InitialContextSetupResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceSetupListCxtRes CRITICALITY ignore TYPE PDUSessionResourceSetupListCxtRes PRESENCE optional }| + { ID id-PDUSessionResourceFailedToSetupListCxtRes CRITICALITY ignore TYPE PDUSessionResourceFailedToSetupListCxtRes PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- INITIAL CONTEXT SETUP FAILURE +-- +-- ************************************************************** + +InitialContextSetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {InitialContextSetupFailureIEs} }, + ... +} + +InitialContextSetupFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceFailedToSetupListCxtFail CRITICALITY ignore TYPE PDUSessionResourceFailedToSetupListCxtFail PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE Context Release Request Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE REQUEST +-- +-- ************************************************************** + +UEContextReleaseRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UEContextReleaseRequest-IEs} }, + ... +} + +UEContextReleaseRequest-IEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceListCxtRelReq CRITICALITY reject TYPE PDUSessionResourceListCxtRelReq PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE Context Release Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE COMMAND +-- +-- ************************************************************** + +UEContextReleaseCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UEContextReleaseCommand-IEs} }, + ... +} + +UEContextReleaseCommand-IEs NGAP-PROTOCOL-IES ::= { + { ID id-UE-NGAP-IDs CRITICALITY reject TYPE UE-NGAP-IDs PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT RELEASE COMPLETE +-- +-- ************************************************************** + +UEContextReleaseComplete ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UEContextReleaseComplete-IEs} }, + ... +} + +UEContextReleaseComplete-IEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE optional }| + { ID id-InfoOnRecommendedCellsAndRANNodesForPaging CRITICALITY ignore TYPE InfoOnRecommendedCellsAndRANNodesForPaging PRESENCE optional }| + { ID id-PDUSessionResourceListCxtRelCpl CRITICALITY reject TYPE PDUSessionResourceListCxtRelCpl PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE Context Modification Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION REQUEST +-- +-- ************************************************************** + +UEContextModificationRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UEContextModificationRequestIEs} }, + ... +} + +UEContextModificationRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RANPagingPriority CRITICALITY ignore TYPE RANPagingPriority PRESENCE optional }| + { ID id-SecurityKey CRITICALITY reject TYPE SecurityKey PRESENCE optional }| + { ID id-IndexToRFSP CRITICALITY ignore TYPE IndexToRFSP PRESENCE optional }| + { ID id-UEAggregateMaximumBitRate CRITICALITY ignore TYPE UEAggregateMaximumBitRate PRESENCE optional }| + { ID id-UESecurityCapabilities CRITICALITY reject TYPE UESecurityCapabilities PRESENCE optional }| + { ID id-CoreNetworkAssistanceInformationForInactive CRITICALITY ignore TYPE CoreNetworkAssistanceInformationForInactive PRESENCE optional }| + { ID id-EmergencyFallbackIndicator CRITICALITY reject TYPE EmergencyFallbackIndicator PRESENCE optional }| + { ID id-NewAMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE optional }| + { ID id-RRCInactiveTransitionReportRequest CRITICALITY ignore TYPE RRCInactiveTransitionReportRequest PRESENCE optional }| + { ID id-NewGUAMI CRITICALITY reject TYPE GUAMI PRESENCE optional }| + { ID id-CNAssistedRANTuning CRITICALITY ignore TYPE CNAssistedRANTuning PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION RESPONSE +-- +-- ************************************************************** + +UEContextModificationResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UEContextModificationResponseIEs} }, + ... +} + +UEContextModificationResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RRCState CRITICALITY ignore TYPE RRCState PRESENCE optional }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE CONTEXT MODIFICATION FAILURE +-- +-- ************************************************************** + +UEContextModificationFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UEContextModificationFailureIEs} }, + ... +} + +UEContextModificationFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- RRC INACTIVE TRANSITION REPORT +-- +-- ************************************************************** + +RRCInactiveTransitionReport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {RRCInactiveTransitionReportIEs} }, + ... +} + +RRCInactiveTransitionReportIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RRCState CRITICALITY ignore TYPE RRCState PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE MOBILITY MANAGEMENT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Handover Preparation Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- HANDOVER REQUIRED +-- +-- ************************************************************** + +HandoverRequired ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {HandoverRequiredIEs} }, + ... +} + +HandoverRequiredIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TargetID CRITICALITY reject TYPE TargetID PRESENCE mandatory }| + { ID id-DirectForwardingPathAvailability CRITICALITY ignore TYPE DirectForwardingPathAvailability PRESENCE optional }| + { ID id-PDUSessionResourceListHORqd CRITICALITY reject TYPE PDUSessionResourceListHORqd PRESENCE mandatory }| + { ID id-SourceToTarget-TransparentContainer CRITICALITY reject TYPE SourceToTarget-TransparentContainer PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- HANDOVER COMMAND +-- +-- ************************************************************** + +HandoverCommand ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {HandoverCommandIEs} }, + ... +} + +HandoverCommandIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory }| + { ID id-NASSecurityParametersFromNGRAN CRITICALITY reject TYPE NASSecurityParametersFromNGRAN PRESENCE conditional }| + -- This IE shall be present if HandoverType IE is set to value "5GStoEPPS" -- + { ID id-PDUSessionResourceHandoverList CRITICALITY ignore TYPE PDUSessionResourceHandoverList PRESENCE optional }| + { ID id-PDUSessionResourceToReleaseListHOCmd CRITICALITY ignore TYPE PDUSessionResourceToReleaseListHOCmd PRESENCE optional }| + { ID id-TargetToSource-TransparentContainer CRITICALITY reject TYPE TargetToSource-TransparentContainer PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- HANDOVER PREPARATION FAILURE +-- +-- ************************************************************** + +HandoverPreparationFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {HandoverPreparationFailureIEs} }, + ... +} + +HandoverPreparationFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- Handover Resource Allocation Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- HANDOVER REQUEST +-- +-- ************************************************************** + +HandoverRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {HandoverRequestIEs} }, + ... +} + +HandoverRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-HandoverType CRITICALITY reject TYPE HandoverType PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-UEAggregateMaximumBitRate CRITICALITY reject TYPE UEAggregateMaximumBitRate PRESENCE mandatory }| + { ID id-CoreNetworkAssistanceInformationForInactive CRITICALITY ignore TYPE CoreNetworkAssistanceInformationForInactive PRESENCE optional }| + { ID id-UESecurityCapabilities CRITICALITY reject TYPE UESecurityCapabilities PRESENCE mandatory }| + { ID id-SecurityContext CRITICALITY reject TYPE SecurityContext PRESENCE mandatory }| + { ID id-NewSecurityContextInd CRITICALITY reject TYPE NewSecurityContextInd PRESENCE optional }| + { ID id-NASC CRITICALITY reject TYPE NAS-PDU PRESENCE optional }| + { ID id-PDUSessionResourceSetupListHOReq CRITICALITY reject TYPE PDUSessionResourceSetupListHOReq PRESENCE mandatory }| + { ID id-AllowedNSSAI CRITICALITY reject TYPE AllowedNSSAI PRESENCE mandatory }| + { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE optional }| + { ID id-MaskedIMEISV CRITICALITY ignore TYPE MaskedIMEISV PRESENCE optional }| + { ID id-SourceToTarget-TransparentContainer CRITICALITY reject TYPE SourceToTarget-TransparentContainer PRESENCE mandatory }| + { ID id-MobilityRestrictionList CRITICALITY ignore TYPE MobilityRestrictionList PRESENCE optional }| + { ID id-LocationReportingRequestType CRITICALITY ignore TYPE LocationReportingRequestType PRESENCE optional }| + { ID id-RRCInactiveTransitionReportRequest CRITICALITY ignore TYPE RRCInactiveTransitionReportRequest PRESENCE optional }| + { ID id-GUAMI CRITICALITY reject TYPE GUAMI PRESENCE mandatory }| + { ID id-RedirectionVoiceFallback CRITICALITY ignore TYPE RedirectionVoiceFallback PRESENCE optional }| + { ID id-CNAssistedRANTuning CRITICALITY ignore TYPE CNAssistedRANTuning PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- HANDOVER REQUEST ACKNOWLEDGE +-- +-- ************************************************************** + +HandoverRequestAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {HandoverRequestAcknowledgeIEs} }, + ... +} + +HandoverRequestAcknowledgeIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceAdmittedList CRITICALITY ignore TYPE PDUSessionResourceAdmittedList PRESENCE mandatory }| + { ID id-PDUSessionResourceFailedToSetupListHOAck CRITICALITY ignore TYPE PDUSessionResourceFailedToSetupListHOAck PRESENCE optional }| + { ID id-TargetToSource-TransparentContainer CRITICALITY reject TYPE TargetToSource-TransparentContainer PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- HANDOVER FAILURE +-- +-- ************************************************************** + +HandoverFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { HandoverFailureIEs} }, + ... +} + +HandoverFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- Handover Notification Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- HANDOVER NOTIFY +-- +-- ************************************************************** + +HandoverNotify ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { HandoverNotifyIEs} }, + ... +} + +HandoverNotifyIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- Path Switch Request Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PATH SWITCH REQUEST +-- +-- ************************************************************** + +PathSwitchRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { PathSwitchRequestIEs} }, + ... +} + +PathSwitchRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-SourceAMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE mandatory }| + { ID id-UESecurityCapabilities CRITICALITY ignore TYPE UESecurityCapabilities PRESENCE mandatory }| + { ID id-PDUSessionResourceToBeSwitchedDLList CRITICALITY reject TYPE PDUSessionResourceToBeSwitchedDLList PRESENCE mandatory }| + { ID id-PDUSessionResourceFailedToSetupListPSReq CRITICALITY ignore TYPE PDUSessionResourceFailedToSetupListPSReq PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- PATH SWITCH REQUEST ACKNOWLEDGE +-- +-- ************************************************************** + +PathSwitchRequestAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { PathSwitchRequestAcknowledgeIEs} }, + ... +} + +PathSwitchRequestAcknowledgeIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UESecurityCapabilities CRITICALITY reject TYPE UESecurityCapabilities PRESENCE optional }| + { ID id-SecurityContext CRITICALITY reject TYPE SecurityContext PRESENCE mandatory }| + { ID id-NewSecurityContextInd CRITICALITY reject TYPE NewSecurityContextInd PRESENCE optional }| + { ID id-PDUSessionResourceSwitchedList CRITICALITY ignore TYPE PDUSessionResourceSwitchedList PRESENCE mandatory }| + { ID id-PDUSessionResourceReleasedListPSAck CRITICALITY ignore TYPE PDUSessionResourceReleasedListPSAck PRESENCE optional }| + { ID id-AllowedNSSAI CRITICALITY reject TYPE AllowedNSSAI PRESENCE mandatory }| + { ID id-CoreNetworkAssistanceInformationForInactive CRITICALITY ignore TYPE CoreNetworkAssistanceInformationForInactive PRESENCE optional }| + { ID id-RRCInactiveTransitionReportRequest CRITICALITY ignore TYPE RRCInactiveTransitionReportRequest PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-RedirectionVoiceFallback CRITICALITY ignore TYPE RedirectionVoiceFallback PRESENCE optional }| + { ID id-CNAssistedRANTuning CRITICALITY ignore TYPE CNAssistedRANTuning PRESENCE optional }, + ... +} + + +-- ************************************************************** +-- +-- PATH SWITCH REQUEST FAILURE +-- +-- ************************************************************** + +PathSwitchRequestFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { PathSwitchRequestFailureIEs} }, + ... +} + +PathSwitchRequestFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceReleasedListPSFail CRITICALITY ignore TYPE PDUSessionResourceReleasedListPSFail PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- Handover Cancellation Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- HANDOVER CANCEL +-- +-- ************************************************************** + +HandoverCancel ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { HandoverCancelIEs} }, + ... +} + +HandoverCancelIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- HANDOVER CANCEL ACKNOWLEDGE +-- +-- ************************************************************** + +HandoverCancelAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { { HandoverCancelAcknowledgeIEs} }, + ... +} + +HandoverCancelAcknowledgeIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- Uplink RAN Status Transfer Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UPLINK RAN STATUS TRANSFER +-- +-- ************************************************************** + +UplinkRANStatusTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UplinkRANStatusTransferIEs} }, + ... +} + +UplinkRANStatusTransferIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RANStatusTransfer-TransparentContainer CRITICALITY reject TYPE RANStatusTransfer-TransparentContainer PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- Downlink RAN Status Transfer Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- DOWNLINK RAN STATUS TRANSFER +-- +-- ************************************************************** + +DownlinkRANStatusTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DownlinkRANStatusTransferIEs} }, + ... +} + +DownlinkRANStatusTransferIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RANStatusTransfer-TransparentContainer CRITICALITY reject TYPE RANStatusTransfer-TransparentContainer PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- PAGING ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PAGING +-- +-- ************************************************************** + +Paging ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PagingIEs} }, + ... +} + +PagingIEs NGAP-PROTOCOL-IES ::= { + { ID id-UEPagingIdentity CRITICALITY ignore TYPE UEPagingIdentity PRESENCE mandatory }| + { ID id-PagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE optional }| + { ID id-TAIListForPaging CRITICALITY ignore TYPE TAIListForPaging PRESENCE mandatory }| + { ID id-PagingPriority CRITICALITY ignore TYPE PagingPriority PRESENCE optional }| + { ID id-UERadioCapabilityForPaging CRITICALITY ignore TYPE UERadioCapabilityForPaging PRESENCE optional }| + { ID id-PagingOrigin CRITICALITY ignore TYPE PagingOrigin PRESENCE optional }| + { ID id-AssistanceDataForPaging CRITICALITY ignore TYPE AssistanceDataForPaging PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- NAS TRANSPORT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- INITIAL UE MESSAGE +-- +-- ************************************************************** + +InitialUEMessage ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {InitialUEMessage-IEs} }, + ... +} + +InitialUEMessage-IEs NGAP-PROTOCOL-IES ::= { + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY reject TYPE UserLocationInformation PRESENCE mandatory }| + { ID id-RRCEstablishmentCause CRITICALITY ignore TYPE RRCEstablishmentCause PRESENCE mandatory }| + { ID id-FiveG-S-TMSI CRITICALITY reject TYPE FiveG-S-TMSI PRESENCE optional }| + { ID id-AMFSetID CRITICALITY ignore TYPE AMFSetID PRESENCE optional }| + { ID id-UEContextRequest CRITICALITY ignore TYPE UEContextRequest PRESENCE optional }| + { ID id-AllowedNSSAI CRITICALITY reject TYPE AllowedNSSAI PRESENCE optional }| + { ID id-SourceToTarget-AMFInformationReroute CRITICALITY ignore TYPE SourceToTarget-AMFInformationReroute PRESENCE optional }| + { ID id-SelectedPLMNIdentity CRITICALITY ignore TYPE PLMNIdentity PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- DOWNLINK NAS TRANSPORT +-- +-- ************************************************************** + +DownlinkNASTransport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DownlinkNASTransport-IEs} }, + ... +} + +DownlinkNASTransport-IEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-OldAMF CRITICALITY reject TYPE AMFName PRESENCE optional }| + { ID id-RANPagingPriority CRITICALITY ignore TYPE RANPagingPriority PRESENCE optional }| + { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE mandatory }| + { ID id-MobilityRestrictionList CRITICALITY ignore TYPE MobilityRestrictionList PRESENCE optional }| + { ID id-IndexToRFSP CRITICALITY ignore TYPE IndexToRFSP PRESENCE optional }| + { ID id-UEAggregateMaximumBitRate CRITICALITY ignore TYPE UEAggregateMaximumBitRate PRESENCE optional }| + { ID id-AllowedNSSAI CRITICALITY reject TYPE AllowedNSSAI PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UPLINK NAS TRANSPORT +-- +-- ************************************************************** + +UplinkNASTransport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UplinkNASTransport-IEs} }, + ... +} + +UplinkNASTransport-IEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-NAS-PDU CRITICALITY reject TYPE NAS-PDU PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- NAS NON DELIVERY INDICATION +-- +-- ************************************************************** + +NASNonDeliveryIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {NASNonDeliveryIndication-IEs} }, + ... +} + +NASNonDeliveryIndication-IEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-NAS-PDU CRITICALITY ignore TYPE NAS-PDU PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- REROUTE NAS REQUEST +-- +-- ************************************************************** + +RerouteNASRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {RerouteNASRequest-IEs} }, + ... +} + +RerouteNASRequest-IEs NGAP-PROTOCOL-IES ::= { + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE optional }| + { ID id-NGAP-Message CRITICALITY reject TYPE OCTET STRING PRESENCE mandatory }| + { ID id-AMFSetID CRITICALITY reject TYPE AMFSetID PRESENCE mandatory }| + { ID id-AllowedNSSAI CRITICALITY reject TYPE AllowedNSSAI PRESENCE optional }| + { ID id-SourceToTarget-AMFInformationReroute CRITICALITY ignore TYPE SourceToTarget-AMFInformationReroute PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- INTERFACE MANAGEMENT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- NG Setup Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- NG SETUP REQUEST +-- +-- ************************************************************** + +NGSetupRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {NGSetupRequestIEs} }, + ... +} + +NGSetupRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-GlobalRANNodeID CRITICALITY reject TYPE GlobalRANNodeID PRESENCE mandatory }| + { ID id-RANNodeName CRITICALITY ignore TYPE RANNodeName PRESENCE optional}| + { ID id-SupportedTAList CRITICALITY reject TYPE SupportedTAList PRESENCE mandatory }| + { ID id-DefaultPagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE mandatory }| + { ID id-UERetentionInformation CRITICALITY ignore TYPE UERetentionInformation PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- NG SETUP RESPONSE +-- +-- ************************************************************** + +NGSetupResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {NGSetupResponseIEs} }, + ... +} + +NGSetupResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMFName CRITICALITY reject TYPE AMFName PRESENCE mandatory }| + { ID id-ServedGUAMIList CRITICALITY reject TYPE ServedGUAMIList PRESENCE mandatory }| + { ID id-RelativeAMFCapacity CRITICALITY ignore TYPE RelativeAMFCapacity PRESENCE mandatory }| + { ID id-PLMNSupportList CRITICALITY reject TYPE PLMNSupportList PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }| + { ID id-UERetentionInformation CRITICALITY ignore TYPE UERetentionInformation PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- NG SETUP FAILURE +-- +-- ************************************************************** + +NGSetupFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {NGSetupFailureIEs} }, + ... +} + +NGSetupFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- RAN Configuration Update Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- RAN CONFIGURATION UPDATE +-- +-- ************************************************************** + +RANConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {RANConfigurationUpdateIEs} }, + ... +} + +RANConfigurationUpdateIEs NGAP-PROTOCOL-IES ::= { + { ID id-RANNodeName CRITICALITY ignore TYPE RANNodeName PRESENCE optional }| + { ID id-SupportedTAList CRITICALITY reject TYPE SupportedTAList PRESENCE optional }| + { ID id-DefaultPagingDRX CRITICALITY ignore TYPE PagingDRX PRESENCE optional }| + { ID id-GlobalRANNodeID CRITICALITY ignore TYPE GlobalRANNodeID PRESENCE optional }| + { ID id-NGRAN-TNLAssociationToRemoveList CRITICALITY reject TYPE NGRAN-TNLAssociationToRemoveList PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- RAN CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +RANConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {RANConfigurationUpdateAcknowledgeIEs} }, + ... +} + +RANConfigurationUpdateAcknowledgeIEs NGAP-PROTOCOL-IES ::= { + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- RAN CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +RANConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {RANConfigurationUpdateFailureIEs} }, + ... +} + +RANConfigurationUpdateFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, +... +} + +-- ************************************************************** +-- +-- AMF Configuration Update Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- AMF CONFIGURATION UPDATE +-- +-- ************************************************************** + +AMFConfigurationUpdate ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {AMFConfigurationUpdateIEs} }, + ... +} + +AMFConfigurationUpdateIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMFName CRITICALITY reject TYPE AMFName PRESENCE optional }| + { ID id-ServedGUAMIList CRITICALITY reject TYPE ServedGUAMIList PRESENCE optional }| + { ID id-RelativeAMFCapacity CRITICALITY ignore TYPE RelativeAMFCapacity PRESENCE optional }| + { ID id-PLMNSupportList CRITICALITY reject TYPE PLMNSupportList PRESENCE optional }| + { ID id-AMF-TNLAssociationToAddList CRITICALITY ignore TYPE AMF-TNLAssociationToAddList PRESENCE optional }| + { ID id-AMF-TNLAssociationToRemoveList CRITICALITY ignore TYPE AMF-TNLAssociationToRemoveList PRESENCE optional }| + { ID id-AMF-TNLAssociationToUpdateList CRITICALITY ignore TYPE AMF-TNLAssociationToUpdateList PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- AMF CONFIGURATION UPDATE ACKNOWLEDGE +-- +-- ************************************************************** + +AMFConfigurationUpdateAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {AMFConfigurationUpdateAcknowledgeIEs} }, + ... +} + +AMFConfigurationUpdateAcknowledgeIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-TNLAssociationSetupList CRITICALITY ignore TYPE AMF-TNLAssociationSetupList PRESENCE optional }| + { ID id-AMF-TNLAssociationFailedToSetupList CRITICALITY ignore TYPE TNLAssociationList PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- AMF CONFIGURATION UPDATE FAILURE +-- +-- ************************************************************** + +AMFConfigurationUpdateFailure ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {AMFConfigurationUpdateFailureIEs} }, + ... +} + +AMFConfigurationUpdateFailureIEs NGAP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-TimeToWait CRITICALITY ignore TYPE TimeToWait PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- AMF Status Indication Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- AMF STATUS INDICATION +-- +-- ************************************************************** + +AMFStatusIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {AMFStatusIndicationIEs} }, + ... +} + +AMFStatusIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-UnavailableGUAMIList CRITICALITY reject TYPE UnavailableGUAMIList PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- NG Reset Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- NG RESET +-- +-- ************************************************************** + +NGReset ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {NGResetIEs} }, + ... +} + +NGResetIEs NGAP-PROTOCOL-IES ::= { + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }| + { ID id-ResetType CRITICALITY reject TYPE ResetType PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- NG RESET ACKNOWLEDGE +-- +-- ************************************************************** + +NGResetAcknowledge ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {NGResetAcknowledgeIEs} }, + ... +} + +NGResetAcknowledgeIEs NGAP-PROTOCOL-IES ::= { + { ID id-UE-associatedLogicalNG-connectionList CRITICALITY ignore TYPE UE-associatedLogicalNG-connectionList PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- Error Indication Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- ERROR INDICATION +-- +-- ************************************************************** + +ErrorIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {ErrorIndicationIEs} }, + ... +} + +ErrorIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE optional }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE optional }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- OVERLOAD START +-- +-- ************************************************************** + +OverloadStart ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {OverloadStartIEs} }, + ... +} + +OverloadStartIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMFOverloadResponse CRITICALITY reject TYPE OverloadResponse PRESENCE optional }| + { ID id-AMFTrafficLoadReductionIndication CRITICALITY ignore TYPE TrafficLoadReductionIndication PRESENCE optional }| + { ID id-OverloadStartNSSAIList CRITICALITY ignore TYPE OverloadStartNSSAIList PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- OVERLOAD STOP +-- +-- ************************************************************** + +OverloadStop ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {OverloadStopIEs} }, + ... +} + +OverloadStopIEs NGAP-PROTOCOL-IES ::= { + ... +} + +-- ************************************************************** +-- +-- CONFIGURATION TRANSFER ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UPLINK RAN CONFIGURATION TRANSFER +-- +-- ************************************************************** + +UplinkRANConfigurationTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UplinkRANConfigurationTransferIEs} }, + ... +} + +UplinkRANConfigurationTransferIEs NGAP-PROTOCOL-IES ::= { + { ID id-SONConfigurationTransferUL CRITICALITY ignore TYPE SONConfigurationTransfer PRESENCE optional }| + { ID id-ENDC-SONConfigurationTransferUL CRITICALITY ignore TYPE EN-DCSONConfigurationTransfer PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- DOWNLINK RAN CONFIGURATION TRANSFER +-- +-- ************************************************************** + +DownlinkRANConfigurationTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DownlinkRANConfigurationTransferIEs} }, + ... +} + +DownlinkRANConfigurationTransferIEs NGAP-PROTOCOL-IES ::= { + { ID id-SONConfigurationTransferDL CRITICALITY ignore TYPE SONConfigurationTransfer PRESENCE optional }| + { ID id-ENDC-SONConfigurationTransferDL CRITICALITY ignore TYPE EN-DCSONConfigurationTransfer PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- WARNING MESSAGE TRANSMISSION ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- Write-Replace Warning Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- WRITE-REPLACE WARNING REQUEST +-- +-- ************************************************************** + +WriteReplaceWarningRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {WriteReplaceWarningRequestIEs} }, + ... +} + +WriteReplaceWarningRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-MessageIdentifier CRITICALITY reject TYPE MessageIdentifier PRESENCE mandatory }| + { ID id-SerialNumber CRITICALITY reject TYPE SerialNumber PRESENCE mandatory }| + { ID id-WarningAreaList CRITICALITY ignore TYPE WarningAreaList PRESENCE optional }| + { ID id-RepetitionPeriod CRITICALITY reject TYPE RepetitionPeriod PRESENCE mandatory }| + { ID id-NumberOfBroadcastsRequested CRITICALITY reject TYPE NumberOfBroadcastsRequested PRESENCE mandatory }| + { ID id-WarningType CRITICALITY ignore TYPE WarningType PRESENCE optional }| + { ID id-WarningSecurityInfo CRITICALITY ignore TYPE WarningSecurityInfo PRESENCE optional }| + { ID id-DataCodingScheme CRITICALITY ignore TYPE DataCodingScheme PRESENCE optional }| + { ID id-WarningMessageContents CRITICALITY ignore TYPE WarningMessageContents PRESENCE optional }| + { ID id-ConcurrentWarningMessageInd CRITICALITY reject TYPE ConcurrentWarningMessageInd PRESENCE optional }| + { ID id-WarningAreaCoordinates CRITICALITY ignore TYPE WarningAreaCoordinates PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- WRITE-REPLACE WARNING RESPONSE +-- +-- ************************************************************** + +WriteReplaceWarningResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {WriteReplaceWarningResponseIEs} }, + ... +} + +WriteReplaceWarningResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-MessageIdentifier CRITICALITY reject TYPE MessageIdentifier PRESENCE mandatory }| + { ID id-SerialNumber CRITICALITY reject TYPE SerialNumber PRESENCE mandatory }| + { ID id-BroadcastCompletedAreaList CRITICALITY ignore TYPE BroadcastCompletedAreaList PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PWS Cancel Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PWS CANCEL REQUEST +-- +-- ************************************************************** + +PWSCancelRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PWSCancelRequestIEs} }, + ... +} + +PWSCancelRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-MessageIdentifier CRITICALITY reject TYPE MessageIdentifier PRESENCE mandatory }| + { ID id-SerialNumber CRITICALITY reject TYPE SerialNumber PRESENCE mandatory }| + { ID id-WarningAreaList CRITICALITY ignore TYPE WarningAreaList PRESENCE optional }| + { ID id-CancelAllWarningMessages CRITICALITY reject TYPE CancelAllWarningMessages PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PWS CANCEL RESPONSE +-- +-- ************************************************************** + +PWSCancelResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PWSCancelResponseIEs} }, + ... +} + +PWSCancelResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-MessageIdentifier CRITICALITY reject TYPE MessageIdentifier PRESENCE mandatory }| + { ID id-SerialNumber CRITICALITY reject TYPE SerialNumber PRESENCE mandatory }| + { ID id-BroadcastCancelledAreaList CRITICALITY ignore TYPE BroadcastCancelledAreaList PRESENCE optional }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PWS Restart Indication Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PWS RESTART INDICATION +-- +-- ************************************************************** + +PWSRestartIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PWSRestartIndicationIEs} }, + ... +} + +PWSRestartIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-CellIDListForRestart CRITICALITY reject TYPE CellIDListForRestart PRESENCE mandatory }| + { ID id-GlobalRANNodeID CRITICALITY reject TYPE GlobalRANNodeID PRESENCE mandatory }| + { ID id-TAIListForRestart CRITICALITY reject TYPE TAIListForRestart PRESENCE mandatory }| + { ID id-EmergencyAreaIDListForRestart CRITICALITY reject TYPE EmergencyAreaIDListForRestart PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PWS Failure Indication Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PWS FAILURE INDICATION +-- +-- ************************************************************** + +PWSFailureIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PWSFailureIndicationIEs} }, + ... +} + +PWSFailureIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-PWSFailedCellIDList CRITICALITY reject TYPE PWSFailedCellIDList PRESENCE mandatory }| + { ID id-GlobalRANNodeID CRITICALITY reject TYPE GlobalRANNodeID PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- NRPPA TRANSPORT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- DOWNLINK UE ASSOCIATED NRPPA TRANSPORT +-- +-- ************************************************************** + +DownlinkUEAssociatedNRPPaTransport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DownlinkUEAssociatedNRPPaTransportIEs} }, + ... +} + +DownlinkUEAssociatedNRPPaTransportIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RoutingID CRITICALITY reject TYPE RoutingID PRESENCE mandatory }| + { ID id-NRPPa-PDU CRITICALITY reject TYPE NRPPa-PDU PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UPLINK UE ASSOCIATED NRPPA TRANSPORT +-- +-- ************************************************************** + +UplinkUEAssociatedNRPPaTransport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UplinkUEAssociatedNRPPaTransportIEs} }, + ... +} + +UplinkUEAssociatedNRPPaTransportIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RoutingID CRITICALITY reject TYPE RoutingID PRESENCE mandatory }| + { ID id-NRPPa-PDU CRITICALITY reject TYPE NRPPa-PDU PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT +-- +-- ************************************************************** + +DownlinkNonUEAssociatedNRPPaTransport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DownlinkNonUEAssociatedNRPPaTransportIEs} }, + ... +} + +DownlinkNonUEAssociatedNRPPaTransportIEs NGAP-PROTOCOL-IES ::= { + { ID id-RoutingID CRITICALITY reject TYPE RoutingID PRESENCE mandatory }| + { ID id-NRPPa-PDU CRITICALITY reject TYPE NRPPa-PDU PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UPLINK NON UE ASSOCIATED NRPPA TRANSPORT +-- +-- ************************************************************** + +UplinkNonUEAssociatedNRPPaTransport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UplinkNonUEAssociatedNRPPaTransportIEs} }, + ... +} + +UplinkNonUEAssociatedNRPPaTransportIEs NGAP-PROTOCOL-IES ::= { + { ID id-RoutingID CRITICALITY reject TYPE RoutingID PRESENCE mandatory }| + { ID id-NRPPa-PDU CRITICALITY reject TYPE NRPPa-PDU PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- TRACE ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- TRACE START +-- +-- ************************************************************** + +TraceStart ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {TraceStartIEs} }, + ... +} + +TraceStartIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-TraceActivation CRITICALITY ignore TYPE TraceActivation PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- TRACE FAILURE INDICATION +-- +-- ************************************************************** + +TraceFailureIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {TraceFailureIndicationIEs} }, + ... +} + +TraceFailureIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-NGRANTraceID CRITICALITY ignore TYPE NGRANTraceID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- DEACTIVATE TRACE +-- +-- ************************************************************** + +DeactivateTrace ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {DeactivateTraceIEs} }, + ... +} + +DeactivateTraceIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-NGRANTraceID CRITICALITY ignore TYPE NGRANTraceID PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- CELL TRAFFIC TRACE +-- +-- ************************************************************** + +CellTrafficTrace ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {CellTrafficTraceIEs} }, + ... +} + +CellTrafficTraceIEs NGAP-PROTOCOL-IES ::= { + {ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + {ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + {ID id-NGRANTraceID CRITICALITY ignore TYPE NGRANTraceID PRESENCE mandatory }| + {ID id-NGRAN-CGI CRITICALITY ignore TYPE NGRAN-CGI PRESENCE mandatory }| + {ID id-TraceCollectionEntityIPAddress CRITICALITY ignore TYPE TransportLayerAddress PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- LOCATION REPORTING ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- LOCATION REPORTING CONTROL +-- +-- ************************************************************** + +LocationReportingControl ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {LocationReportingControlIEs} }, + ... +} + +LocationReportingControlIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-LocationReportingRequestType CRITICALITY ignore TYPE LocationReportingRequestType PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- LOCATION REPORTING FAILURE INDICATION +-- +-- ************************************************************** + +LocationReportingFailureIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {LocationReportingFailureIndicationIEs} }, + ... +} + +LocationReportingFailureIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-Cause CRITICALITY ignore TYPE Cause PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- LOCATION REPORT +-- +-- ************************************************************** + +LocationReport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {LocationReportIEs} }, + ... +} + +LocationReportIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE mandatory }| + { ID id-UEPresenceInAreaOfInterestList CRITICALITY ignore TYPE UEPresenceInAreaOfInterestList PRESENCE optional }| + { ID id-LocationReportingRequestType CRITICALITY ignore TYPE LocationReportingRequestType PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE TNLA BINDING ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE TNLA BINDING RELEASE REQUEST +-- +-- ************************************************************** + +UETNLABindingReleaseRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UETNLABindingReleaseRequestIEs} }, + ... +} + +UETNLABindingReleaseRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }, + ... +} + +-- ************************************************************** +-- +-- UE RADIO CAPABILITY MANAGEMENT ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE RADIO CAPABILITY INFO INDICATION +-- +-- ************************************************************** + +UERadioCapabilityInfoIndication ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UERadioCapabilityInfoIndicationIEs} }, + ... +} + +UERadioCapabilityInfoIndicationIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UERadioCapability CRITICALITY ignore TYPE UERadioCapability PRESENCE mandatory }| + { ID id-UERadioCapabilityForPaging CRITICALITY ignore TYPE UERadioCapabilityForPaging PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE Radio Capability Check Elementary Procedure +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- UE RADIO CAPABILITY CHECK REQUEST +-- +-- ************************************************************** + +UERadioCapabilityCheckRequest ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UERadioCapabilityCheckRequestIEs} }, + ... +} + +UERadioCapabilityCheckRequestIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY reject TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY reject TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-UERadioCapability CRITICALITY ignore TYPE UERadioCapability PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- UE RADIO CAPABILITY CHECK RESPONSE +-- +-- ************************************************************** + +UERadioCapabilityCheckResponse ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {UERadioCapabilityCheckResponseIEs} }, + ... +} + +UERadioCapabilityCheckResponseIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-IMSVoiceSupportIndicator CRITICALITY reject TYPE IMSVoiceSupportIndicator PRESENCE mandatory }| + { ID id-CriticalityDiagnostics CRITICALITY ignore TYPE CriticalityDiagnostics PRESENCE optional }, + ... +} + +-- ************************************************************** +-- +-- PRIVATE MESSAGE ELEMENTARY PROCEDURE +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- PRIVATE MESSAGE +-- +-- ************************************************************** + +PrivateMessage ::= SEQUENCE { + privateIEs PrivateIE-Container { { PrivateMessageIEs } }, + ... +} + +PrivateMessageIEs NGAP-PRIVATE-IES ::= { + ... +} + + +-- ************************************************************** +-- +-- DATA USAGE REPORTING ELEMENTARY PROCEDURES +-- +-- ************************************************************** + +-- ************************************************************** +-- +-- SECONDARY RAT DATA USAGE REPORT +-- +-- ************************************************************** + +SecondaryRATDataUsageReport ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {SecondaryRATDataUsageReportIEs} }, + ... +} + +SecondaryRATDataUsageReportIEs NGAP-PROTOCOL-IES ::= { + { ID id-AMF-UE-NGAP-ID CRITICALITY ignore TYPE AMF-UE-NGAP-ID PRESENCE mandatory }| + { ID id-RAN-UE-NGAP-ID CRITICALITY ignore TYPE RAN-UE-NGAP-ID PRESENCE mandatory }| + { ID id-PDUSessionResourceSecondaryRATUsageList CRITICALITY ignore TYPE PDUSessionResourceSecondaryRATUsageList PRESENCE mandatory }| + { ID id-HandoverFlag CRITICALITY ignore TYPE HandoverFlag PRESENCE optional }| + { ID id-UserLocationInformation CRITICALITY ignore TYPE UserLocationInformation PRESENCE optional }, + ... +} + + +END +-- ASN1STOP + +-- ASN1START +-- ************************************************************** +-- +-- Information Element Definitions +-- +-- ************************************************************** + +NGAP-IEs { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-IEs (2) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +IMPORTS + + id-AdditionalDLForwardingUPTNLInformation, + id-AdditionalULForwardingUPTNLInformation, + id-AdditionalDLQosFlowPerTNLInformation, + id-AdditionalDLUPTNLInformationForHOList, + id-AdditionalNGU-UP-TNLInformation, + id-AdditionalUL-NGU-UP-TNLInformation, + id-Cause, + id-CNTypeRestrictionsForEquivalent, + id-CNTypeRestrictionsForServing, + id-CommonNetworkInstance, + id-DataForwardingNotPossible, + id-DL-NGU-UP-TNLInformation, + id-EndpointIPAddressAndPort, + id-LastEUTRAN-PLMNIdentity, + id-LocationReportingAdditionalInfo, + id-MaximumIntegrityProtectedDataRate-DL, + id-NetworkInstance, + id-OldAssociatedQosFlowList-ULendmarkerexpected, + id-PDUSessionAggregateMaximumBitRate, + id-PDUSessionResourceFailedToSetupListCxtFail, + id-PDUSessionResourceReleaseResponseTransfer, + id-PDUSessionType, + id-PSCellInformation, + id-QosFlowAddOrModifyRequestList, + id-QosFlowSetupRequestList, + id-QosFlowToReleaseList, + id-SCTP-TLAs, + id-SecondaryRATUsageInformation, + id-SecurityIndication, + id-SecurityResult, + id-S-NSSAI, + id-TNLAssociationTransportLayerAddressNGRAN, + id-UL-NGU-UP-TNLInformation, + id-UL-NGU-UP-TNLModifyList, + id-ULForwarding, + id-ULForwardingUP-TNLInformation, + maxnoofAllowedAreas, + maxnoofAllowedS-NSSAIs, + maxnoofBPLMNs, + maxnoofCellIDforWarning, + maxnoofCellinAoI, + maxnoofCellinEAI, + maxnoofCellsingNB, + maxnoofCellsinngeNB, + maxnoofCellinTAI, + maxnoofCellsinUEHistoryInfo, + maxnoofCellsUEMovingTrajectory, + maxnoofDRBs, + maxnoofEmergencyAreaID, + maxnoofEAIforRestart, + maxnoofEPLMNs, + maxnoofEPLMNsPlusOne, + maxnoofE-RABs, + maxnoofErrors, + maxnoofForbTACs, + maxnoofMultiConnectivity, + maxnoofMultiConnectivityMinusOne, + maxnoofNGConnectionsToReset, + maxnoofPDUSessions, + maxnoofPLMNs, + maxnoofQosFlows, + maxnoofRANNodeinAoI, + maxnoofRecommendedCells, + maxnoofRecommendedRANNodes, + maxnoofAoI, + maxnoofServedGUAMIs, + maxnoofSliceItems, + maxnoofTACs, + maxnoofTAIforInactive, + maxnoofTAIforPaging, + maxnoofTAIforRestart, + maxnoofTAIforWarning, + maxnoofTAIinAoI, + maxnoofTimePeriods, + maxnoofTNLAssociations, + maxnoofXnExtTLAs, + maxnoofXnGTP-TLAs, + maxnoofXnTLAs + +FROM NGAP-Constants + + Criticality, + ProcedureCode, + ProtocolIE-ID, + TriggeringMessage +FROM NGAP-CommonDataTypes + + ProtocolExtensionContainer{}, + ProtocolIE-Container{}, + NGAP-PROTOCOL-EXTENSION, + ProtocolIE-SingleContainer{}, + NGAP-PROTOCOL-IES +FROM NGAP-Containers; + +-- A + +AdditionalDLUPTNLInformationForHOList ::= SEQUENCE (SIZE(1..maxnoofMultiConnectivityMinusOne)) OF AdditionalDLUPTNLInformationForHOItem + +AdditionalDLUPTNLInformationForHOItem ::= SEQUENCE { + additionalDL-NGU-UP-TNLInformation UPTransportLayerInformation, + additionalQosFlowSetupResponseList QosFlowListWithDataForwarding, + additionalDLForwardingUPTNLInformation UPTransportLayerInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { AdditionalDLUPTNLInformationForHOItem-ExtIEs} } OPTIONAL, + ... +} + +AdditionalDLUPTNLInformationForHOItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AdditionalQosFlowInformation ::= ENUMERATED { + more-likely, + ... +} + +AllocationAndRetentionPriority ::= SEQUENCE { + priorityLevelARP PriorityLevelARP, + pre-emptionCapability Pre-emptionCapability, + pre-emptionVulnerability Pre-emptionVulnerability, + iE-Extensions ProtocolExtensionContainer { {AllocationAndRetentionPriority-ExtIEs} } OPTIONAL, + ... +} + +AllocationAndRetentionPriority-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AllowedNSSAI ::= SEQUENCE (SIZE(1..maxnoofAllowedS-NSSAIs)) OF AllowedNSSAI-Item + +AllowedNSSAI-Item ::= SEQUENCE { + s-NSSAI S-NSSAI, + iE-Extensions ProtocolExtensionContainer { {AllowedNSSAI-Item-ExtIEs} } OPTIONAL, + ... +} + +AllowedNSSAI-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AllowedTACs ::= SEQUENCE (SIZE(1..maxnoofAllowedAreas)) OF TAC + +AMFName ::= PrintableString (SIZE(1..150, ...)) + +AMFPagingTarget ::= CHOICE { + globalRANNodeID GlobalRANNodeID, + tAI TAI, + choice-Extensions ProtocolIE-SingleContainer { {AMFPagingTarget-ExtIEs} } +} + +AMFPagingTarget-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +AMFPointer ::= BIT STRING (SIZE(6)) + +AMFRegionID ::= BIT STRING (SIZE(8)) + +AMFSetID ::= BIT STRING (SIZE(10)) + +AMF-TNLAssociationSetupList ::= SEQUENCE (SIZE(1..maxnoofTNLAssociations)) OF AMF-TNLAssociationSetupItem + +AMF-TNLAssociationSetupItem ::= SEQUENCE { + aMF-TNLAssociationAddress CPTransportLayerInformation, + iE-Extensions ProtocolExtensionContainer { {AMF-TNLAssociationSetupItem-ExtIEs} } OPTIONAL, + ... +} + +AMF-TNLAssociationSetupItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AMF-TNLAssociationToAddList ::= SEQUENCE (SIZE(1..maxnoofTNLAssociations)) OF AMF-TNLAssociationToAddItem + +AMF-TNLAssociationToAddItem ::= SEQUENCE { + aMF-TNLAssociationAddress CPTransportLayerInformation, + tNLAssociationUsage TNLAssociationUsage OPTIONAL, + tNLAddressWeightFactor TNLAddressWeightFactor, + iE-Extensions ProtocolExtensionContainer { {AMF-TNLAssociationToAddItem-ExtIEs} } OPTIONAL, + ... +} + +AMF-TNLAssociationToAddItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AMF-TNLAssociationToRemoveList ::= SEQUENCE (SIZE(1..maxnoofTNLAssociations)) OF AMF-TNLAssociationToRemoveItem + +AMF-TNLAssociationToRemoveItem ::= SEQUENCE { + aMF-TNLAssociationAddress CPTransportLayerInformation, + iE-Extensions ProtocolExtensionContainer { {AMF-TNLAssociationToRemoveItem-ExtIEs} } OPTIONAL, + ... +} + +AMF-TNLAssociationToRemoveItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + {ID id-TNLAssociationTransportLayerAddressNGRAN CRITICALITY reject EXTENSION CPTransportLayerInformation PRESENCE optional}, + ... +} + +AMF-TNLAssociationToUpdateList ::= SEQUENCE (SIZE(1..maxnoofTNLAssociations)) OF AMF-TNLAssociationToUpdateItem + +AMF-TNLAssociationToUpdateItem ::= SEQUENCE { + aMF-TNLAssociationAddress CPTransportLayerInformation, + tNLAssociationUsage TNLAssociationUsage OPTIONAL, + tNLAddressWeightFactor TNLAddressWeightFactor OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {AMF-TNLAssociationToUpdateItem-ExtIEs} } OPTIONAL, + ... +} + +AMF-TNLAssociationToUpdateItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AMF-UE-NGAP-ID ::= INTEGER (0..1099511627775) + +AreaOfInterest ::= SEQUENCE { + areaOfInterestTAIList AreaOfInterestTAIList OPTIONAL, + areaOfInterestCellList AreaOfInterestCellList OPTIONAL, + areaOfInterestRANNodeList AreaOfInterestRANNodeList OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {AreaOfInterest-ExtIEs} } OPTIONAL, + ... +} + +AreaOfInterest-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AreaOfInterestCellList ::= SEQUENCE (SIZE(1..maxnoofCellinAoI)) OF AreaOfInterestCellItem + +AreaOfInterestCellItem ::= SEQUENCE { + nGRAN-CGI NGRAN-CGI, + iE-Extensions ProtocolExtensionContainer { {AreaOfInterestCellItem-ExtIEs} } OPTIONAL, + ... +} + +AreaOfInterestCellItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AreaOfInterestList ::= SEQUENCE (SIZE(1..maxnoofAoI)) OF AreaOfInterestItem + +AreaOfInterestItem ::= SEQUENCE { + areaOfInterest AreaOfInterest, + locationReportingReferenceID LocationReportingReferenceID, + iE-Extensions ProtocolExtensionContainer { {AreaOfInterestItem-ExtIEs} } OPTIONAL, + ... +} + +AreaOfInterestItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AreaOfInterestRANNodeList ::= SEQUENCE (SIZE(1..maxnoofRANNodeinAoI)) OF AreaOfInterestRANNodeItem + +AreaOfInterestRANNodeItem ::= SEQUENCE { + globalRANNodeID GlobalRANNodeID, + iE-Extensions ProtocolExtensionContainer { {AreaOfInterestRANNodeItem-ExtIEs} } OPTIONAL, + ... +} + +AreaOfInterestRANNodeItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AreaOfInterestTAIList ::= SEQUENCE (SIZE(1..maxnoofTAIinAoI)) OF AreaOfInterestTAIItem + +AreaOfInterestTAIItem ::= SEQUENCE { + tAI TAI, + iE-Extensions ProtocolExtensionContainer { {AreaOfInterestTAIItem-ExtIEs} } OPTIONAL, + ... +} + +AreaOfInterestTAIItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AssistanceDataForPaging ::= SEQUENCE { + assistanceDataForRecommendedCells AssistanceDataForRecommendedCells OPTIONAL, + pagingAttemptInformation PagingAttemptInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {AssistanceDataForPaging-ExtIEs} } OPTIONAL, + ... +} + +AssistanceDataForPaging-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AssistanceDataForRecommendedCells ::= SEQUENCE { + recommendedCellsForPaging RecommendedCellsForPaging, + iE-Extensions ProtocolExtensionContainer { {AssistanceDataForRecommendedCells-ExtIEs} } OPTIONAL, + ... +} + +AssistanceDataForRecommendedCells-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AssociatedQosFlowList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF AssociatedQosFlowItem + +AssociatedQosFlowItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + qosFlowMappingIndication ENUMERATED {ul, dl, ...} OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {AssociatedQosFlowItem-ExtIEs} } OPTIONAL, + ... +} + +AssociatedQosFlowItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +AveragingWindow ::= INTEGER (0..4095, ...) + +-- B + +BitRate ::= INTEGER (0..4000000000000, ...) + +BroadcastCancelledAreaList ::= CHOICE { + cellIDCancelledEUTRA CellIDCancelledEUTRA, + tAICancelledEUTRA TAICancelledEUTRA, + emergencyAreaIDCancelledEUTRA EmergencyAreaIDCancelledEUTRA, + cellIDCancelledNR CellIDCancelledNR, + tAICancelledNR TAICancelledNR, + emergencyAreaIDCancelledNR EmergencyAreaIDCancelledNR, + choice-Extensions ProtocolIE-SingleContainer { {BroadcastCancelledAreaList-ExtIEs} } +} + +BroadcastCancelledAreaList-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +BroadcastCompletedAreaList ::= CHOICE { + cellIDBroadcastEUTRA CellIDBroadcastEUTRA, + tAIBroadcastEUTRA TAIBroadcastEUTRA, + emergencyAreaIDBroadcastEUTRA EmergencyAreaIDBroadcastEUTRA, + cellIDBroadcastNR CellIDBroadcastNR, + tAIBroadcastNR TAIBroadcastNR, + emergencyAreaIDBroadcastNR EmergencyAreaIDBroadcastNR, + choice-Extensions ProtocolIE-SingleContainer { {BroadcastCompletedAreaList-ExtIEs} } +} + +BroadcastCompletedAreaList-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +BroadcastPLMNList ::= SEQUENCE (SIZE(1..maxnoofBPLMNs)) OF BroadcastPLMNItem + +BroadcastPLMNItem ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + tAISliceSupportList SliceSupportList, + iE-Extensions ProtocolExtensionContainer { {BroadcastPLMNItem-ExtIEs} } OPTIONAL, + ... +} + +BroadcastPLMNItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- C + +CancelAllWarningMessages ::= ENUMERATED { + true, + ... +} + +CancelledCellsInEAI-EUTRA ::= SEQUENCE (SIZE(1..maxnoofCellinEAI)) OF CancelledCellsInEAI-EUTRA-Item + +CancelledCellsInEAI-EUTRA-Item ::= SEQUENCE { + eUTRA-CGI EUTRA-CGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { {CancelledCellsInEAI-EUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +CancelledCellsInEAI-EUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CancelledCellsInEAI-NR ::= SEQUENCE (SIZE(1..maxnoofCellinEAI)) OF CancelledCellsInEAI-NR-Item + +CancelledCellsInEAI-NR-Item ::= SEQUENCE { + nR-CGI NR-CGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { {CancelledCellsInEAI-NR-Item-ExtIEs} } OPTIONAL, + ... +} + +CancelledCellsInEAI-NR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CancelledCellsInTAI-EUTRA ::= SEQUENCE (SIZE(1..maxnoofCellinTAI)) OF CancelledCellsInTAI-EUTRA-Item + +CancelledCellsInTAI-EUTRA-Item ::= SEQUENCE { + eUTRA-CGI EUTRA-CGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { {CancelledCellsInTAI-EUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +CancelledCellsInTAI-EUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CancelledCellsInTAI-NR ::= SEQUENCE (SIZE(1..maxnoofCellinTAI)) OF CancelledCellsInTAI-NR-Item + +CancelledCellsInTAI-NR-Item ::= SEQUENCE{ + nR-CGI NR-CGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { {CancelledCellsInTAI-NR-Item-ExtIEs} } OPTIONAL, + ... +} + +CancelledCellsInTAI-NR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +Cause ::= CHOICE { + radioNetwork CauseRadioNetwork, + transport CauseTransport, + nas CauseNas, + protocol CauseProtocol, + misc CauseMisc, + choice-Extensions ProtocolIE-SingleContainer { {Cause-ExtIEs} } +} + +Cause-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +CauseMisc ::= ENUMERATED { + control-processing-overload, + not-enough-user-plane-processing-resources, + hardware-failure, + om-intervention, + unknown-PLMN, + unspecified, + ... +} + +CauseNas ::= ENUMERATED { + normal-release, + authentication-failure, + deregister, + unspecified, + ... +} + +CauseProtocol ::= ENUMERATED { + transfer-syntax-error, + abstract-syntax-error-reject, + abstract-syntax-error-ignore-and-notify, + message-not-compatible-with-receiver-state, + semantic-error, + abstract-syntax-error-falsely-constructed-message, + unspecified, + ... +} + +CauseRadioNetwork ::= ENUMERATED { + unspecified, + txnrelocoverall-expiry, + successful-handover, + release-due-to-ngran-generated-reason, + release-due-to-5gc-generated-reason, + handover-cancelled, + partial-handover, + ho-failure-in-target-5GC-ngran-node-or-target-system, + ho-target-not-allowed, + tngrelocoverall-expiry, + tngrelocprep-expiry, + cell-not-available, + unknown-targetID, + no-radio-resources-available-in-target-cell, + unknown-local-UE-NGAP-ID, + inconsistent-remote-UE-NGAP-ID, + handover-desirable-for-radio-reason, + time-critical-handover, + resource-optimisation-handover, + reduce-load-in-serving-cell, + user-inactivity, + radio-connection-with-ue-lost, + radio-resources-not-available, + invalid-qos-combination, + failure-in-radio-interface-procedure, + interaction-with-other-procedure, + unknown-PDU-session-ID, + unkown-qos-flow-ID, + multiple-PDU-session-ID-instances, + multiple-qos-flow-ID-instances, + encryption-and-or-integrity-protection-algorithms-not-supported, + ng-intra-system-handover-triggered, + ng-inter-system-handover-triggered, + xn-handover-triggered, + not-supported-5QI-value, + ue-context-transfer, + ims-voice-eps-fallback-or-rat-fallback-triggered, + up-integrity-protection-not-possible, + up-confidentiality-protection-not-possible, + slice-not-supported, + ue-in-rrc-inactive-state-not-reachable, + redirection, + resources-not-available-for-the-slice, + ue-max-integrity-protected-data-rate-reason, + release-due-to-cn-detected-mobility, + ..., + n26-interface-not-available, + release-due-to-pre-emption, + multiple-location-reporting-reference-ID-instances +} + +CauseTransport ::= ENUMERATED { + transport-resource-unavailable, + unspecified, + ... +} + +CellIDBroadcastEUTRA ::= SEQUENCE (SIZE(1..maxnoofCellIDforWarning)) OF CellIDBroadcastEUTRA-Item + +CellIDBroadcastEUTRA-Item ::= SEQUENCE { + eUTRA-CGI EUTRA-CGI, + iE-Extensions ProtocolExtensionContainer { {CellIDBroadcastEUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +CellIDBroadcastEUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CellIDBroadcastNR ::= SEQUENCE (SIZE(1..maxnoofCellIDforWarning)) OF CellIDBroadcastNR-Item + +CellIDBroadcastNR-Item ::= SEQUENCE { + nR-CGI NR-CGI, + iE-Extensions ProtocolExtensionContainer { {CellIDBroadcastNR-Item-ExtIEs} } OPTIONAL, + ... +} + +CellIDBroadcastNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CellIDCancelledEUTRA ::= SEQUENCE (SIZE(1..maxnoofCellIDforWarning)) OF CellIDCancelledEUTRA-Item + +CellIDCancelledEUTRA-Item ::= SEQUENCE { + eUTRA-CGI EUTRA-CGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { {CellIDCancelledEUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +CellIDCancelledEUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CellIDCancelledNR ::= SEQUENCE (SIZE(1..maxnoofCellIDforWarning)) OF CellIDCancelledNR-Item + +CellIDCancelledNR-Item ::= SEQUENCE { + nR-CGI NR-CGI, + numberOfBroadcasts NumberOfBroadcasts, + iE-Extensions ProtocolExtensionContainer { {CellIDCancelledNR-Item-ExtIEs} } OPTIONAL, + ... +} + +CellIDCancelledNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CellIDListForRestart ::= CHOICE { + eUTRA-CGIListforRestart EUTRA-CGIList, + nR-CGIListforRestart NR-CGIList, + choice-Extensions ProtocolIE-SingleContainer { {CellIDListForRestart-ExtIEs} } +} + +CellIDListForRestart-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +CellSize ::= ENUMERATED {verysmall, small, medium, large, ...} + + +CellType ::= SEQUENCE { + cellSize CellSize, + iE-Extensions ProtocolExtensionContainer { {CellType-ExtIEs} } OPTIONAL, + ... +} + +CellType-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CNAssistedRANTuning ::= SEQUENCE { + expectedUEBehaviour ExpectedUEBehaviour OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CNAssistedRANTuning-ExtIEs} } OPTIONAL, + ... +} + +CNAssistedRANTuning-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CNTypeRestrictionsForEquivalent ::= SEQUENCE (SIZE(1..maxnoofEPLMNs)) OF CNTypeRestrictionsForEquivalentItem + +CNTypeRestrictionsForEquivalentItem ::= SEQUENCE { + plmnIdentity PLMNIdentity, + cn-Type ENUMERATED {epc-forbidden, fiveGC-forbidden, ...}, + iE-Extensions ProtocolExtensionContainer { {CNTypeRestrictionsForEquivalentItem-ExtIEs} } OPTIONAL, + ... +} + +CNTypeRestrictionsForEquivalentItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::={ + ... +} + +CNTypeRestrictionsForServing ::= ENUMERATED { + epc-forbidden, + ... +} + +CommonNetworkInstance ::= OCTET STRING + +CompletedCellsInEAI-EUTRA ::= SEQUENCE (SIZE(1..maxnoofCellinEAI)) OF CompletedCellsInEAI-EUTRA-Item + +CompletedCellsInEAI-EUTRA-Item ::= SEQUENCE { + eUTRA-CGI EUTRA-CGI, + iE-Extensions ProtocolExtensionContainer { {CompletedCellsInEAI-EUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +CompletedCellsInEAI-EUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CompletedCellsInEAI-NR ::= SEQUENCE (SIZE(1..maxnoofCellinEAI)) OF CompletedCellsInEAI-NR-Item + +CompletedCellsInEAI-NR-Item ::= SEQUENCE { + nR-CGI NR-CGI, + iE-Extensions ProtocolExtensionContainer { {CompletedCellsInEAI-NR-Item-ExtIEs} } OPTIONAL, + ... +} + +CompletedCellsInEAI-NR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CompletedCellsInTAI-EUTRA ::= SEQUENCE (SIZE(1..maxnoofCellinTAI)) OF CompletedCellsInTAI-EUTRA-Item + +CompletedCellsInTAI-EUTRA-Item ::= SEQUENCE{ + eUTRA-CGI EUTRA-CGI, + iE-Extensions ProtocolExtensionContainer { {CompletedCellsInTAI-EUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +CompletedCellsInTAI-EUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CompletedCellsInTAI-NR ::= SEQUENCE (SIZE(1..maxnoofCellinTAI)) OF CompletedCellsInTAI-NR-Item + +CompletedCellsInTAI-NR-Item ::= SEQUENCE{ + nR-CGI NR-CGI, + iE-Extensions ProtocolExtensionContainer { {CompletedCellsInTAI-NR-Item-ExtIEs} } OPTIONAL, + ... +} + +CompletedCellsInTAI-NR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +ConcurrentWarningMessageInd ::= ENUMERATED { + true, + ... +} + +ConfidentialityProtectionIndication ::= ENUMERATED { + required, + preferred, + not-needed, + ... +} + +ConfidentialityProtectionResult ::= ENUMERATED { + performed, + not-performed, + ... +} + +CoreNetworkAssistanceInformationForInactive ::= SEQUENCE { + uEIdentityIndexValue UEIdentityIndexValue, + uESpecificDRX PagingDRX OPTIONAL, + periodicRegistrationUpdateTimer PeriodicRegistrationUpdateTimer, + mICOModeIndication MICOModeIndication OPTIONAL, + tAIListForInactive TAIListForInactive, + expectedUEBehaviour ExpectedUEBehaviour OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {CoreNetworkAssistanceInformationForInactive-ExtIEs} } OPTIONAL, + ... +} + +CoreNetworkAssistanceInformationForInactive-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +COUNTValueForPDCP-SN12 ::= SEQUENCE { + pDCP-SN12 INTEGER (0..4095), + hFN-PDCP-SN12 INTEGER (0..1048575), + iE-Extensions ProtocolExtensionContainer { {COUNTValueForPDCP-SN12-ExtIEs} } OPTIONAL, + ... +} + +COUNTValueForPDCP-SN12-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +COUNTValueForPDCP-SN18 ::= SEQUENCE { + pDCP-SN18 INTEGER (0..262143), + hFN-PDCP-SN18 INTEGER (0..16383), + iE-Extensions ProtocolExtensionContainer { {COUNTValueForPDCP-SN18-ExtIEs} } OPTIONAL, + ... +} + +COUNTValueForPDCP-SN18-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CPTransportLayerInformation ::= CHOICE { + endpointIPAddress TransportLayerAddress, + choice-Extensions ProtocolIE-SingleContainer { {CPTransportLayerInformation-ExtIEs} } +} + +CPTransportLayerInformation-ExtIEs NGAP-PROTOCOL-IES ::= { + { ID id-EndpointIPAddressAndPort CRITICALITY reject TYPE EndpointIPAddressAndPort PRESENCE mandatory}, + ... +} + +CriticalityDiagnostics ::= SEQUENCE { + procedureCode ProcedureCode OPTIONAL, + triggeringMessage TriggeringMessage OPTIONAL, + procedureCriticality Criticality OPTIONAL, + iEsCriticalityDiagnostics CriticalityDiagnostics-IE-List OPTIONAL, + iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-ExtIEs}} OPTIONAL, + ... +} + +CriticalityDiagnostics-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE(1..maxnoofErrors)) OF CriticalityDiagnostics-IE-Item + +CriticalityDiagnostics-IE-Item ::= SEQUENCE { + iECriticality Criticality, + iE-ID ProtocolIE-ID, + typeOfError TypeOfError, + iE-Extensions ProtocolExtensionContainer {{CriticalityDiagnostics-IE-Item-ExtIEs}} OPTIONAL, + ... +} + +CriticalityDiagnostics-IE-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- D + +DataCodingScheme ::= BIT STRING (SIZE(8)) + +DataForwardingAccepted ::= ENUMERATED { + data-forwarding-accepted, + ... +} + +DataForwardingNotPossible ::= ENUMERATED { + data-forwarding-not-possible, + ... +} + +DataForwardingResponseDRBList ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF DataForwardingResponseDRBItem + +DataForwardingResponseDRBItem ::= SEQUENCE { + dRB-ID DRB-ID, + dLForwardingUP-TNLInformation UPTransportLayerInformation OPTIONAL, + uLForwardingUP-TNLInformation UPTransportLayerInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer {{DataForwardingResponseDRBItem-ExtIEs}} OPTIONAL, + ... +} + +DataForwardingResponseDRBItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +DelayCritical ::= ENUMERATED { + delay-critical, + non-delay-critical, + ... +} + +DLForwarding ::= ENUMERATED { + dl-forwarding-proposed, + ... +} + +DL-NGU-TNLInformationReused ::= ENUMERATED { + true, + ... +} + +DirectForwardingPathAvailability ::= ENUMERATED { + direct-path-available, + ... +} + +DRB-ID ::= INTEGER (1..32, ...) + +DRBsSubjectToStatusTransferList ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF DRBsSubjectToStatusTransferItem + +DRBsSubjectToStatusTransferItem ::= SEQUENCE { + dRB-ID DRB-ID, + dRBStatusUL DRBStatusUL, + dRBStatusDL DRBStatusDL, + iE-Extension ProtocolExtensionContainer { {DRBsSubjectToStatusTransferItem-ExtIEs} } OPTIONAL, + ... +} + +DRBsSubjectToStatusTransferItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-OldAssociatedQosFlowList-ULendmarkerexpected CRITICALITY reject EXTENSION AssociatedQosFlowList PRESENCE optional }, + ... +} + +DRBStatusDL ::= CHOICE { + dRBStatusDL12 DRBStatusDL12, + dRBStatusDL18 DRBStatusDL18, + choice-Extensions ProtocolIE-SingleContainer { {DRBStatusDL-ExtIEs} } +} + +DRBStatusDL-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +DRBStatusDL12 ::= SEQUENCE { + dL-COUNTValue COUNTValueForPDCP-SN12, + iE-Extension ProtocolExtensionContainer { {DRBStatusDL12-ExtIEs} } OPTIONAL, + ... +} + +DRBStatusDL12-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBStatusDL18 ::= SEQUENCE { + dL-COUNTValue COUNTValueForPDCP-SN18, + iE-Extension ProtocolExtensionContainer { {DRBStatusDL18-ExtIEs} } OPTIONAL, + ... +} + +DRBStatusDL18-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBStatusUL ::= CHOICE { + dRBStatusUL12 DRBStatusUL12, + dRBStatusUL18 DRBStatusUL18, + choice-Extensions ProtocolIE-SingleContainer { {DRBStatusUL-ExtIEs} } +} + +DRBStatusUL-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +DRBStatusUL12 ::= SEQUENCE { + uL-COUNTValue COUNTValueForPDCP-SN12, + receiveStatusOfUL-PDCP-SDUs BIT STRING (SIZE(1..2048)) OPTIONAL, + iE-Extension ProtocolExtensionContainer { {DRBStatusUL12-ExtIEs} } OPTIONAL, + ... +} + +DRBStatusUL12-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBStatusUL18 ::= SEQUENCE { + uL-COUNTValue COUNTValueForPDCP-SN18, + receiveStatusOfUL-PDCP-SDUs BIT STRING (SIZE(1..131072)) OPTIONAL, + iE-Extension ProtocolExtensionContainer { {DRBStatusUL18-ExtIEs} } OPTIONAL, + ... +} + +DRBStatusUL18-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +DRBsToQosFlowsMappingList ::= SEQUENCE (SIZE(1..maxnoofDRBs)) OF DRBsToQosFlowsMappingItem + +DRBsToQosFlowsMappingItem ::= SEQUENCE { + dRB-ID DRB-ID, + associatedQosFlowList AssociatedQosFlowList, + iE-Extensions ProtocolExtensionContainer { {DRBsToQosFlowsMappingItem-ExtIEs} } OPTIONAL, + ... +} + +DRBsToQosFlowsMappingItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +Dynamic5QIDescriptor ::= SEQUENCE { + priorityLevelQos PriorityLevelQos, + packetDelayBudget PacketDelayBudget, + packetErrorRate PacketErrorRate, + fiveQI FiveQI OPTIONAL, + delayCritical DelayCritical OPTIONAL, +-- The above IE shall be present in case of GBR QoS flow + averagingWindow AveragingWindow OPTIONAL, +-- The above IE shall be present in case of GBR QoS flow + maximumDataBurstVolume MaximumDataBurstVolume OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {Dynamic5QIDescriptor-ExtIEs} } OPTIONAL, + ... +} + +Dynamic5QIDescriptor-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- E + +EmergencyAreaID ::= OCTET STRING (SIZE(3)) + +EmergencyAreaIDBroadcastEUTRA ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaIDBroadcastEUTRA-Item + +EmergencyAreaIDBroadcastEUTRA-Item ::= SEQUENCE { + emergencyAreaID EmergencyAreaID, + completedCellsInEAI-EUTRA CompletedCellsInEAI-EUTRA, + iE-Extensions ProtocolExtensionContainer { {EmergencyAreaIDBroadcastEUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +EmergencyAreaIDBroadcastEUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EmergencyAreaIDBroadcastNR ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaIDBroadcastNR-Item + +EmergencyAreaIDBroadcastNR-Item ::= SEQUENCE { + emergencyAreaID EmergencyAreaID, + completedCellsInEAI-NR CompletedCellsInEAI-NR, + iE-Extensions ProtocolExtensionContainer { {EmergencyAreaIDBroadcastNR-Item-ExtIEs} } OPTIONAL, + ... +} + +EmergencyAreaIDBroadcastNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EmergencyAreaIDCancelledEUTRA ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaIDCancelledEUTRA-Item + +EmergencyAreaIDCancelledEUTRA-Item ::= SEQUENCE { + emergencyAreaID EmergencyAreaID, + cancelledCellsInEAI-EUTRA CancelledCellsInEAI-EUTRA, + iE-Extensions ProtocolExtensionContainer { {EmergencyAreaIDCancelledEUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +EmergencyAreaIDCancelledEUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EmergencyAreaIDCancelledNR ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaIDCancelledNR-Item + +EmergencyAreaIDCancelledNR-Item ::= SEQUENCE { + emergencyAreaID EmergencyAreaID, + cancelledCellsInEAI-NR CancelledCellsInEAI-NR, + iE-Extensions ProtocolExtensionContainer { {EmergencyAreaIDCancelledNR-Item-ExtIEs} } OPTIONAL, + ... +} + +EmergencyAreaIDCancelledNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EmergencyAreaIDList ::= SEQUENCE (SIZE(1..maxnoofEmergencyAreaID)) OF EmergencyAreaID + +EmergencyAreaIDListForRestart ::= SEQUENCE (SIZE(1..maxnoofEAIforRestart)) OF EmergencyAreaID + +EmergencyFallbackIndicator ::= SEQUENCE { + emergencyFallbackRequestIndicator EmergencyFallbackRequestIndicator, + emergencyServiceTargetCN EmergencyServiceTargetCN OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {EmergencyFallbackIndicator-ExtIEs} } OPTIONAL, + ... +} + +EmergencyFallbackIndicator-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EmergencyFallbackRequestIndicator ::= ENUMERATED { + emergency-fallback-requested, + ... +} + +EmergencyServiceTargetCN ::= ENUMERATED { + fiveGC, + epc, + ... +} + +EN-DCSONConfigurationTransfer ::= OCTET STRING + +EndpointIPAddressAndPort ::=SEQUENCE { + endpointIPAddress TransportLayerAddress, + portNumber PortNumber, + iE-Extensions ProtocolExtensionContainer { { EndpointIPAddressAndPort-ExtIEs} } OPTIONAL +} + +EndpointIPAddressAndPort-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EquivalentPLMNs ::= SEQUENCE (SIZE(1..maxnoofEPLMNs)) OF PLMNIdentity + +EPS-TAC ::= OCTET STRING (SIZE(2)) + +EPS-TAI ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + ePS-TAC EPS-TAC, + iE-Extensions ProtocolExtensionContainer { {EPS-TAI-ExtIEs} } OPTIONAL, + ... +} + +EPS-TAI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +E-RAB-ID ::= INTEGER (0..15, ...) + +E-RABInformationList ::= SEQUENCE (SIZE(1..maxnoofE-RABs)) OF E-RABInformationItem + +E-RABInformationItem ::= SEQUENCE { + e-RAB-ID E-RAB-ID, + dLForwarding DLForwarding OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {E-RABInformationItem-ExtIEs} } OPTIONAL, + ... +} + +E-RABInformationItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRACellIdentity ::= BIT STRING (SIZE(28)) + +EUTRA-CGI ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + eUTRACellIdentity EUTRACellIdentity, + iE-Extensions ProtocolExtensionContainer { {EUTRA-CGI-ExtIEs} } OPTIONAL, + ... +} + +EUTRA-CGI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +EUTRA-CGIList ::= SEQUENCE (SIZE(1..maxnoofCellsinngeNB)) OF EUTRA-CGI + +EUTRA-CGIListForWarning ::= SEQUENCE (SIZE(1..maxnoofCellIDforWarning)) OF EUTRA-CGI + +EUTRAencryptionAlgorithms ::= BIT STRING (SIZE(16, ...)) + +EUTRAintegrityProtectionAlgorithms ::= BIT STRING (SIZE(16, ...)) + +EventType ::= ENUMERATED { + direct, + change-of-serve-cell, + ue-presence-in-area-of-interest, + stop-change-of-serve-cell, + stop-ue-presence-in-area-of-interest, + cancel-location-reporting-for-the-ue, + ... +} + +ExpectedActivityPeriod ::= INTEGER (1..30|40|50|60|80|100|120|150|180|181, ...) + +ExpectedHOInterval ::= ENUMERATED { + sec15, sec30, sec60, sec90, sec120, sec180, long-time, + ... +} + +ExpectedIdlePeriod ::= INTEGER (1..30|40|50|60|80|100|120|150|180|181, ...) + +ExpectedUEActivityBehaviour ::= SEQUENCE { + expectedActivityPeriod ExpectedActivityPeriod OPTIONAL, + expectedIdlePeriod ExpectedIdlePeriod OPTIONAL, + sourceOfUEActivityBehaviourInformation SourceOfUEActivityBehaviourInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {ExpectedUEActivityBehaviour-ExtIEs} } OPTIONAL, + ... +} + +ExpectedUEActivityBehaviour-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +ExpectedUEBehaviour ::= SEQUENCE { + expectedUEActivityBehaviour ExpectedUEActivityBehaviour OPTIONAL, + expectedHOInterval ExpectedHOInterval OPTIONAL, + expectedUEMobility ExpectedUEMobility OPTIONAL, + expectedUEMovingTrajectory ExpectedUEMovingTrajectory OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {ExpectedUEBehaviour-ExtIEs} } OPTIONAL, + ... +} + +ExpectedUEBehaviour-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +ExpectedUEMobility ::= ENUMERATED { + stationary, + mobile, + ... +} + +ExpectedUEMovingTrajectory ::= SEQUENCE (SIZE(1..maxnoofCellsUEMovingTrajectory)) OF ExpectedUEMovingTrajectoryItem + +ExpectedUEMovingTrajectoryItem ::= SEQUENCE { + nGRAN-CGI NGRAN-CGI, + timeStayedInCell INTEGER (0..4095) OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {ExpectedUEMovingTrajectoryItem-ExtIEs} } OPTIONAL, + ... +} + +ExpectedUEMovingTrajectoryItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- F + +FiveG-S-TMSI ::= SEQUENCE { + aMFSetID AMFSetID, + aMFPointer AMFPointer, + fiveG-TMSI FiveG-TMSI, + iE-Extensions ProtocolExtensionContainer { {FiveG-S-TMSI-ExtIEs} } OPTIONAL, + ... +} + +FiveG-S-TMSI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +FiveG-TMSI ::= OCTET STRING (SIZE(4)) + +FiveQI ::= INTEGER (0..255, ...) + +ForbiddenAreaInformation ::= SEQUENCE (SIZE(1.. maxnoofEPLMNsPlusOne)) OF ForbiddenAreaInformation-Item + +ForbiddenAreaInformation-Item ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + forbiddenTACs ForbiddenTACs, + iE-Extensions ProtocolExtensionContainer { {ForbiddenAreaInformation-Item-ExtIEs} } OPTIONAL, + ... +} + +ForbiddenAreaInformation-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +ForbiddenTACs ::= SEQUENCE (SIZE(1..maxnoofForbTACs)) OF TAC + +-- G + +GBR-QosInformation ::= SEQUENCE { + maximumFlowBitRateDL BitRate, + maximumFlowBitRateUL BitRate, + guaranteedFlowBitRateDL BitRate, + guaranteedFlowBitRateUL BitRate, + notificationControl NotificationControl OPTIONAL, + maximumPacketLossRateDL PacketLossRate OPTIONAL, + maximumPacketLossRateUL PacketLossRate OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {GBR-QosInformation-ExtIEs} } OPTIONAL, + ... +} + +GBR-QosInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ...} + +GlobalGNB-ID ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + gNB-ID GNB-ID, + iE-Extensions ProtocolExtensionContainer { {GlobalGNB-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalGNB-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +GlobalN3IWF-ID ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + n3IWF-ID N3IWF-ID, + iE-Extensions ProtocolExtensionContainer { {GlobalN3IWF-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalN3IWF-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +GlobalNgENB-ID ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + ngENB-ID NgENB-ID, + iE-Extensions ProtocolExtensionContainer { {GlobalNgENB-ID-ExtIEs} } OPTIONAL, + ... +} + +GlobalNgENB-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +GlobalRANNodeID ::= CHOICE { + globalGNB-ID GlobalGNB-ID, + globalNgENB-ID GlobalNgENB-ID, + globalN3IWF-ID GlobalN3IWF-ID, + choice-Extensions ProtocolIE-SingleContainer { {GlobalRANNodeID-ExtIEs} } +} + +GlobalRANNodeID-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +GNB-ID ::= CHOICE { + gNB-ID BIT STRING (SIZE(22..32)), + choice-Extensions ProtocolIE-SingleContainer { {GNB-ID-ExtIEs} } +} + +GNB-ID-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +GTP-TEID ::= OCTET STRING (SIZE(4)) + +GTPTunnel ::= SEQUENCE { + transportLayerAddress TransportLayerAddress, + gTP-TEID GTP-TEID, + iE-Extensions ProtocolExtensionContainer { {GTPTunnel-ExtIEs} } OPTIONAL, + ... +} + +GTPTunnel-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +GUAMI ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + aMFRegionID AMFRegionID, + aMFSetID AMFSetID, + aMFPointer AMFPointer, + iE-Extensions ProtocolExtensionContainer { {GUAMI-ExtIEs} } OPTIONAL, + ... +} + +GUAMI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + + +-- H + +HandoverCommandTransfer ::= SEQUENCE { + dLForwardingUP-TNLInformation UPTransportLayerInformation OPTIONAL, + qosFlowToBeForwardedList QosFlowToBeForwardedList OPTIONAL, + dataForwardingResponseDRBList DataForwardingResponseDRBList OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {HandoverCommandTransfer-ExtIEs} } OPTIONAL, + ... +} + +HandoverCommandTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-AdditionalDLForwardingUPTNLInformation CRITICALITY ignore EXTENSION QosFlowPerTNLInformationList PRESENCE optional}| + { ID id-ULForwardingUP-TNLInformation CRITICALITY reject EXTENSION UPTransportLayerInformation PRESENCE optional}| + { ID id-AdditionalULForwardingUPTNLInformation CRITICALITY reject EXTENSION UPTransportLayerInformationList PRESENCE optional}, + ... +} + +HandoverFlag ::= ENUMERATED { + handover-preparation, + ... +} + +HandoverPreparationUnsuccessfulTransfer ::= SEQUENCE { + cause Cause, + iE-Extensions ProtocolExtensionContainer { {HandoverPreparationUnsuccessfulTransfer-ExtIEs} } OPTIONAL, + ... +} + +HandoverPreparationUnsuccessfulTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +HandoverRequestAcknowledgeTransfer ::= SEQUENCE { + dL-NGU-UP-TNLInformation UPTransportLayerInformation, + dLForwardingUP-TNLInformation UPTransportLayerInformation OPTIONAL, + securityResult SecurityResult OPTIONAL, + qosFlowSetupResponseList QosFlowListWithDataForwarding, + qosFlowFailedToSetupList QosFlowListWithCause OPTIONAL, + dataForwardingResponseDRBList DataForwardingResponseDRBList OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {HandoverRequestAcknowledgeTransfer-ExtIEs} } OPTIONAL, + ... +} + +HandoverRequestAcknowledgeTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-AdditionalDLUPTNLInformationForHOList CRITICALITY ignore EXTENSION AdditionalDLUPTNLInformationForHOList PRESENCE optional }| + { ID id-ULForwardingUP-TNLInformation CRITICALITY reject EXTENSION UPTransportLayerInformation PRESENCE optional}| + { ID id-AdditionalULForwardingUPTNLInformation CRITICALITY reject EXTENSION UPTransportLayerInformationList PRESENCE optional}, + ... +} + +HandoverRequiredTransfer ::= SEQUENCE { + directForwardingPathAvailability DirectForwardingPathAvailability OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {HandoverRequiredTransfer-ExtIEs} } OPTIONAL, + ... +} + +HandoverRequiredTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +HandoverResourceAllocationUnsuccessfulTransfer ::= SEQUENCE { + cause Cause, + criticalityDiagnostics CriticalityDiagnostics OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {HandoverResourceAllocationUnsuccessfulTransfer-ExtIEs} } OPTIONAL, + ... +} + +HandoverResourceAllocationUnsuccessfulTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +HandoverType ::= ENUMERATED { + intra5gs, + fivegs-to-eps, + eps-to-5gs, + ... +} + +-- I + +IMSVoiceSupportIndicator ::= ENUMERATED { + supported, + not-supported, + ... +} + +IndexToRFSP ::= INTEGER (1..256, ...) + +InfoOnRecommendedCellsAndRANNodesForPaging ::= SEQUENCE { + recommendedCellsForPaging RecommendedCellsForPaging, + recommendRANNodesForPaging RecommendedRANNodesForPaging, + iE-Extensions ProtocolExtensionContainer { {InfoOnRecommendedCellsAndRANNodesForPaging-ExtIEs} } OPTIONAL, + ... +} + +InfoOnRecommendedCellsAndRANNodesForPaging-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + + +IntegrityProtectionIndication ::= ENUMERATED { + required, + preferred, + not-needed, + ... +} + +IntegrityProtectionResult ::= ENUMERATED { + performed, + not-performed, + ... +} + +IntendedNumberOfPagingAttempts ::= INTEGER (1..16, ...) + +InterfacesToTrace ::= BIT STRING (SIZE(8)) + +-- J +-- K +-- L + +LastVisitedCellInformation ::= CHOICE { + nGRANCell LastVisitedNGRANCellInformation, + eUTRANCell LastVisitedEUTRANCellInformation, + uTRANCell LastVisitedUTRANCellInformation, + gERANCell LastVisitedGERANCellInformation, + choice-Extensions ProtocolIE-SingleContainer { {LastVisitedCellInformation-ExtIEs} } +} + +LastVisitedCellInformation-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +LastVisitedCellItem ::= SEQUENCE { + lastVisitedCellInformation LastVisitedCellInformation, + iE-Extensions ProtocolExtensionContainer { {LastVisitedCellItem-ExtIEs} } OPTIONAL, + ... +} + +LastVisitedCellItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +LastVisitedEUTRANCellInformation ::= OCTET STRING + +LastVisitedGERANCellInformation ::= OCTET STRING + +LastVisitedNGRANCellInformation::= SEQUENCE { + globalCellID NGRAN-CGI, + cellType CellType, + timeUEStayedInCell TimeUEStayedInCell, + timeUEStayedInCellEnhancedGranularity TimeUEStayedInCellEnhancedGranularity OPTIONAL, + hOCauseValue Cause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {LastVisitedNGRANCellInformation-ExtIEs} } OPTIONAL, + ... +} + +LastVisitedNGRANCellInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +LastVisitedUTRANCellInformation ::= OCTET STRING + +LocationReportingAdditionalInfo ::= ENUMERATED { + includePSCell, + ... +} + +LocationReportingReferenceID ::= INTEGER (1..64, ...) + +LocationReportingRequestType ::= SEQUENCE { + eventType EventType, + reportArea ReportArea, + areaOfInterestList AreaOfInterestList OPTIONAL, + locationReportingReferenceIDToBeCancelled LocationReportingReferenceID OPTIONAL, +-- The above IE shall be present if the event type is set to ¡°stop reporting UE presence in the area of interest¡± + iE-Extensions ProtocolExtensionContainer { {LocationReportingRequestType-ExtIEs} } OPTIONAL, + ... +} + +LocationReportingRequestType-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-LocationReportingAdditionalInfo CRITICALITY ignore EXTENSION LocationReportingAdditionalInfo PRESENCE optional }, + ... +} + +-- M + +MaskedIMEISV ::= BIT STRING (SIZE(64)) + +MaximumDataBurstVolume ::= INTEGER (0..4095, ...) + +MessageIdentifier ::= BIT STRING (SIZE(16)) + +MaximumIntegrityProtectedDataRate ::= ENUMERATED { + bitrate64kbs, + maximum-UE-rate, + ... +} + +MICOModeIndication ::= ENUMERATED { + true, + ... +} + +MobilityRestrictionList ::= SEQUENCE { + servingPLMN PLMNIdentity, + equivalentPLMNs EquivalentPLMNs OPTIONAL, + rATRestrictions RATRestrictions OPTIONAL, + forbiddenAreaInformation ForbiddenAreaInformation OPTIONAL, + serviceAreaInformation ServiceAreaInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {MobilityRestrictionList-ExtIEs} } OPTIONAL, + ... +} + +MobilityRestrictionList-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-LastEUTRAN-PLMNIdentity CRITICALITY ignore EXTENSION PLMNIdentity PRESENCE optional }| + { ID id-CNTypeRestrictionsForServing CRITICALITY ignore EXTENSION CNTypeRestrictionsForServing PRESENCE optional}| + { ID id-CNTypeRestrictionsForEquivalent CRITICALITY ignore EXTENSION CNTypeRestrictionsForEquivalent PRESENCE optional}, + ... +} + + +-- N + +N3IWF-ID ::= CHOICE { + n3IWF-ID BIT STRING (SIZE(16)), + choice-Extensions ProtocolIE-SingleContainer { {N3IWF-ID-ExtIEs} } +} + +N3IWF-ID-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +NAS-PDU ::= OCTET STRING + +NASSecurityParametersFromNGRAN ::= OCTET STRING + +NetworkInstance ::= INTEGER (1..256, ...) + +NewSecurityContextInd ::= ENUMERATED { + true, + ... +} + +NextHopChainingCount ::= INTEGER (0..7) + +NextPagingAreaScope ::= ENUMERATED { + same, + changed, + ... +} + +NgENB-ID ::= CHOICE { + macroNgENB-ID BIT STRING (SIZE(20)), + shortMacroNgENB-ID BIT STRING (SIZE(18)), + longMacroNgENB-ID BIT STRING (SIZE(21)), + choice-Extensions ProtocolIE-SingleContainer { {NgENB-ID-ExtIEs} } +} + +NgENB-ID-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +NGRAN-CGI ::= CHOICE { + nR-CGI NR-CGI, + eUTRA-CGI EUTRA-CGI, + choice-Extensions ProtocolIE-SingleContainer { {NGRAN-CGI-ExtIEs} } +} + +NGRAN-CGI-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +NGRAN-TNLAssociationToRemoveList ::= SEQUENCE (SIZE(1..maxnoofTNLAssociations)) OF NGRAN-TNLAssociationToRemoveItem + +NGRAN-TNLAssociationToRemoveItem::= SEQUENCE { + tNLAssociationTransportLayerAddress CPTransportLayerInformation, + tNLAssociationTransportLayerAddressAMF CPTransportLayerInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { NGRAN-TNLAssociationToRemoveItem-ExtIEs} } OPTIONAL +} + +NGRAN-TNLAssociationToRemoveItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +NGRANTraceID ::= OCTET STRING (SIZE(8)) + +NonDynamic5QIDescriptor ::= SEQUENCE { + fiveQI FiveQI, + priorityLevelQos PriorityLevelQos OPTIONAL, + averagingWindow AveragingWindow OPTIONAL, + maximumDataBurstVolume MaximumDataBurstVolume OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {NonDynamic5QIDescriptor-ExtIEs} } OPTIONAL, + ... +} + +NonDynamic5QIDescriptor-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +NotAllowedTACs ::= SEQUENCE (SIZE(1..maxnoofAllowedAreas)) OF TAC + +NotificationCause ::= ENUMERATED { + fulfilled, + not-fulfilled, + ... +} + +NotificationControl ::= ENUMERATED { + notification-requested, + ... +} + +NRCellIdentity ::= BIT STRING (SIZE(36)) + +NR-CGI ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + nRCellIdentity NRCellIdentity, + iE-Extensions ProtocolExtensionContainer { {NR-CGI-ExtIEs} } OPTIONAL, + ... +} + +NR-CGI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +NR-CGIList ::= SEQUENCE (SIZE(1..maxnoofCellsingNB)) OF NR-CGI + +NR-CGIListForWarning ::= SEQUENCE (SIZE(1..maxnoofCellIDforWarning)) OF NR-CGI + +NRencryptionAlgorithms ::= BIT STRING (SIZE(16, ...)) + +NRintegrityProtectionAlgorithms ::= BIT STRING (SIZE(16, ...)) + +NRPPa-PDU ::= OCTET STRING + +NumberOfBroadcasts ::= INTEGER (0..65535) + +NumberOfBroadcastsRequested ::= INTEGER (0..65535) + +-- O + +OverloadAction ::= ENUMERATED { + reject-non-emergency-mo-dt, + reject-rrc-cr-signalling, + permit-emergency-sessions-and-mobile-terminated-services-only, + permit-high-priority-sessions-and-mobile-terminated-services-only, + ... +} + +OverloadResponse ::= CHOICE { + overloadAction OverloadAction, + choice-Extensions ProtocolIE-SingleContainer { {OverloadResponse-ExtIEs} } +} + +OverloadResponse-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +OverloadStartNSSAIList ::= SEQUENCE (SIZE (1..maxnoofSliceItems)) OF OverloadStartNSSAIItem + +OverloadStartNSSAIItem ::= SEQUENCE { + sliceOverloadList SliceOverloadList, + sliceOverloadResponse OverloadResponse OPTIONAL, + sliceTrafficLoadReductionIndication TrafficLoadReductionIndication OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {OverloadStartNSSAIItem-ExtIEs} } OPTIONAL, + ... +} + +OverloadStartNSSAIItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- P + +PacketDelayBudget ::= INTEGER (0..1023, ...) + +PacketErrorRate ::= SEQUENCE { + pERScalar INTEGER (0..9, ...), + pERExponent INTEGER (0..9, ...), + iE-Extensions ProtocolExtensionContainer { {PacketErrorRate-ExtIEs} } OPTIONAL, + ... +} + +PacketErrorRate-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PacketLossRate ::= INTEGER (0..1000, ...) + +PagingAttemptInformation ::= SEQUENCE { + pagingAttemptCount PagingAttemptCount, + intendedNumberOfPagingAttempts IntendedNumberOfPagingAttempts, + nextPagingAreaScope NextPagingAreaScope OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PagingAttemptInformation-ExtIEs} } OPTIONAL, + ... +} + +PagingAttemptInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PagingAttemptCount ::= INTEGER (1..16, ...) + +PagingDRX ::= ENUMERATED { + v32, + v64, + v128, + v256, + ... +} + +PagingOrigin ::= ENUMERATED { + non-3gpp, + ... +} + +PagingPriority ::= ENUMERATED { + priolevel1, + priolevel2, + priolevel3, + priolevel4, + priolevel5, + priolevel6, + priolevel7, + priolevel8, + ... +} + +PathSwitchRequestAcknowledgeTransfer ::= SEQUENCE { + uL-NGU-UP-TNLInformation UPTransportLayerInformation OPTIONAL, + securityIndication SecurityIndication OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PathSwitchRequestAcknowledgeTransfer-ExtIEs} } OPTIONAL, + ... +} + +PathSwitchRequestAcknowledgeTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-AdditionalNGU-UP-TNLInformation CRITICALITY ignore EXTENSION UPTransportLayerInformationPairList PRESENCE optional }, + ... +} + +PathSwitchRequestSetupFailedTransfer ::= SEQUENCE { + cause Cause, + iE-Extensions ProtocolExtensionContainer { {PathSwitchRequestSetupFailedTransfer-ExtIEs} } OPTIONAL, + ... +} + +PathSwitchRequestSetupFailedTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PathSwitchRequestTransfer ::= SEQUENCE { + dL-NGU-UP-TNLInformation UPTransportLayerInformation, + dL-NGU-TNLInformationReused DL-NGU-TNLInformationReused OPTIONAL, + userPlaneSecurityInformation UserPlaneSecurityInformation OPTIONAL, + qosFlowAcceptedList QosFlowAcceptedList, + iE-Extensions ProtocolExtensionContainer { {PathSwitchRequestTransfer-ExtIEs} } OPTIONAL, + ... +} + +PathSwitchRequestTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-AdditionalDLQosFlowPerTNLInformation CRITICALITY ignore EXTENSION QosFlowPerTNLInformationList PRESENCE optional }, + ... +} + +PathSwitchRequestUnsuccessfulTransfer ::= SEQUENCE { + cause Cause, + iE-Extensions ProtocolExtensionContainer { {PathSwitchRequestUnsuccessfulTransfer-ExtIEs} } OPTIONAL, + ... +} + +PathSwitchRequestUnsuccessfulTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionAggregateMaximumBitRate ::= SEQUENCE { + pDUSessionAggregateMaximumBitRateDL BitRate, + pDUSessionAggregateMaximumBitRateUL BitRate, + iE-Extensions ProtocolExtensionContainer { {PDUSessionAggregateMaximumBitRate-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionAggregateMaximumBitRate-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionID ::= INTEGER (0..255) + +PDUSessionResourceAdmittedList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceAdmittedItem + +PDUSessionResourceAdmittedItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + handoverRequestAcknowledgeTransfer OCTET STRING (CONTAINING HandoverRequestAcknowledgeTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceAdmittedItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceAdmittedItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToModifyListModCfm ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToModifyItemModCfm + +PDUSessionResourceFailedToModifyItemModCfm ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceModifyIndicationUnsuccessfulTransfer OCTET STRING (CONTAINING PDUSessionResourceModifyIndicationUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToModifyItemModCfm-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToModifyItemModCfm-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToModifyListModRes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToModifyItemModRes + +PDUSessionResourceFailedToModifyItemModRes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceModifyUnsuccessfulTransfer OCTET STRING (CONTAINING PDUSessionResourceModifyUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToModifyItemModRes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToModifyItemModRes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToSetupListCxtFail ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToSetupItemCxtFail + +PDUSessionResourceFailedToSetupItemCxtFail ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceSetupUnsuccessfulTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToSetupItemCxtFail-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToSetupItemCxtFail-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToSetupListCxtRes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToSetupItemCxtRes + +PDUSessionResourceFailedToSetupItemCxtRes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceSetupUnsuccessfulTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToSetupItemCxtRes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToSetupItemCxtRes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToSetupListHOAck ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToSetupItemHOAck + +PDUSessionResourceFailedToSetupItemHOAck ::= SEQUENCE { + pDUSessionID PDUSessionID, + handoverResourceAllocationUnsuccessfulTransfer OCTET STRING (CONTAINING HandoverResourceAllocationUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToSetupItemHOAck-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToSetupItemHOAck-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToSetupListPSReq ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToSetupItemPSReq + +PDUSessionResourceFailedToSetupItemPSReq ::= SEQUENCE { + pDUSessionID PDUSessionID, + pathSwitchRequestSetupFailedTransfer OCTET STRING (CONTAINING PathSwitchRequestSetupFailedTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToSetupItemPSReq-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToSetupItemPSReq-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceFailedToSetupListSURes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceFailedToSetupItemSURes + +PDUSessionResourceFailedToSetupItemSURes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceSetupUnsuccessfulTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceFailedToSetupItemSURes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceFailedToSetupItemSURes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceHandoverList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceHandoverItem + +PDUSessionResourceHandoverItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + handoverCommandTransfer OCTET STRING (CONTAINING HandoverCommandTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceHandoverItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceHandoverItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceInformationList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceInformationItem + +PDUSessionResourceInformationItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + qosFlowInformationList QosFlowInformationList, + dRBsToQosFlowsMappingList DRBsToQosFlowsMappingList OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceInformationItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceInformationItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceListCxtRelCpl ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceItemCxtRelCpl + +PDUSessionResourceItemCxtRelCpl ::= SEQUENCE { + pDUSessionID PDUSessionID, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceItemCxtRelCpl-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceItemCxtRelCpl-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-PDUSessionResourceReleaseResponseTransfer CRITICALITY ignore EXTENSION OCTET STRING (CONTAINING PDUSessionResourceReleaseResponseTransfer) PRESENCE optional }, + ... +} + +PDUSessionResourceListCxtRelReq ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceItemCxtRelReq + +PDUSessionResourceItemCxtRelReq ::= SEQUENCE { + pDUSessionID PDUSessionID, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceItemCxtRelReq-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceItemCxtRelReq-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceListHORqd ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceItemHORqd + +PDUSessionResourceItemHORqd ::= SEQUENCE { + pDUSessionID PDUSessionID, + handoverRequiredTransfer OCTET STRING (CONTAINING HandoverRequiredTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceItemHORqd-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceItemHORqd-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceModifyConfirmTransfer ::= SEQUENCE { + qosFlowModifyConfirmList QosFlowModifyConfirmList, + uLNGU-UP-TNLInformation UPTransportLayerInformation, + additionalNG-UUPTNLInformation UPTransportLayerInformationPairList OPTIONAL, + qosFlowFailedToModifyList QosFlowListWithCause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyConfirmTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyConfirmTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceModifyIndicationUnsuccessfulTransfer ::= SEQUENCE { + cause Cause, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyIndicationUnsuccessfulTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyIndicationUnsuccessfulTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceModifyRequestTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceModifyRequestTransferIEs} }, + ... +} + +PDUSessionResourceModifyRequestTransferIEs NGAP-PROTOCOL-IES ::= { + { ID id-PDUSessionAggregateMaximumBitRate CRITICALITY reject TYPE PDUSessionAggregateMaximumBitRate PRESENCE optional }| + { ID id-UL-NGU-UP-TNLModifyList CRITICALITY reject TYPE UL-NGU-UP-TNLModifyList PRESENCE optional }| + { ID id-NetworkInstance CRITICALITY reject TYPE NetworkInstance PRESENCE optional }| + { ID id-QosFlowAddOrModifyRequestList CRITICALITY reject TYPE QosFlowAddOrModifyRequestList PRESENCE optional }| + { ID id-QosFlowToReleaseList CRITICALITY reject TYPE QosFlowListWithCause PRESENCE optional }| + { ID id-AdditionalUL-NGU-UP-TNLInformation CRITICALITY reject TYPE UPTransportLayerInformationList PRESENCE optional }| + { ID id-CommonNetworkInstance CRITICALITY ignore TYPE CommonNetworkInstance PRESENCE optional }, + ... +} + +PDUSessionResourceModifyResponseTransfer ::= SEQUENCE { + dL-NGU-UP-TNLInformation UPTransportLayerInformation OPTIONAL, + uL-NGU-UP-TNLInformation UPTransportLayerInformation OPTIONAL, + qosFlowAddOrModifyResponseList QosFlowAddOrModifyResponseList OPTIONAL, + additionalDLQosFlowPerTNLInformation QosFlowPerTNLInformationList OPTIONAL, + qosFlowFailedToAddOrModifyList QosFlowListWithCause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyResponseTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyResponseTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-AdditionalNGU-UP-TNLInformation CRITICALITY ignore EXTENSION UPTransportLayerInformationPairList PRESENCE optional }, + ... +} + +PDUSessionResourceModifyIndicationTransfer ::= SEQUENCE { + dLQosFlowPerTNLInformation QosFlowPerTNLInformation, + additionalDLQosFlowPerTNLInformation QosFlowPerTNLInformationList OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyIndicationTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyIndicationTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-SecondaryRATUsageInformation CRITICALITY ignore EXTENSION SecondaryRATUsageInformation PRESENCE optional }| + { ID id-SecurityResult CRITICALITY ignore EXTENSION SecurityResult PRESENCE optional }, + ... +} + +PDUSessionResourceModifyListModCfm ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceModifyItemModCfm + +PDUSessionResourceModifyItemModCfm ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceModifyConfirmTransfer OCTET STRING (CONTAINING PDUSessionResourceModifyConfirmTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyItemModCfm-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyItemModCfm-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceModifyListModInd ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceModifyItemModInd + +PDUSessionResourceModifyItemModInd ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceModifyIndicationTransfer OCTET STRING (CONTAINING PDUSessionResourceModifyIndicationTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyItemModInd-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyItemModInd-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceModifyListModReq ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceModifyItemModReq + +PDUSessionResourceModifyItemModReq ::= SEQUENCE { + pDUSessionID PDUSessionID, + nAS-PDU NAS-PDU OPTIONAL, + pDUSessionResourceModifyRequestTransfer OCTET STRING (CONTAINING PDUSessionResourceModifyRequestTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyItemModReq-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyItemModReq-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + {ID id-S-NSSAI CRITICALITY reject EXTENSION S-NSSAI PRESENCE optional }, + ... +} + +PDUSessionResourceModifyListModRes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceModifyItemModRes + +PDUSessionResourceModifyItemModRes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceModifyResponseTransfer OCTET STRING (CONTAINING PDUSessionResourceModifyResponseTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyItemModRes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyItemModRes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceModifyUnsuccessfulTransfer ::= SEQUENCE { + cause Cause, + criticalityDiagnostics CriticalityDiagnostics OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceModifyUnsuccessfulTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceModifyUnsuccessfulTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceNotifyList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceNotifyItem + +PDUSessionResourceNotifyItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceNotifyTransfer OCTET STRING (CONTAINING PDUSessionResourceNotifyTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceNotifyItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceNotifyItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceNotifyReleasedTransfer ::= SEQUENCE { + cause Cause, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceNotifyReleasedTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceNotifyReleasedTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-SecondaryRATUsageInformation CRITICALITY ignore EXTENSION SecondaryRATUsageInformation PRESENCE optional }, + ... +} + +PDUSessionResourceNotifyTransfer ::= SEQUENCE { + qosFlowNotifyList QosFlowNotifyList OPTIONAL, + qosFlowReleasedList QosFlowListWithCause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceNotifyTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceNotifyTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-SecondaryRATUsageInformation CRITICALITY ignore EXTENSION SecondaryRATUsageInformation PRESENCE optional }, + ... +} + +PDUSessionResourceReleaseCommandTransfer ::= SEQUENCE { + cause Cause, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceReleaseCommandTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceReleaseCommandTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceReleasedListNot ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceReleasedItemNot + +PDUSessionResourceReleasedItemNot ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceNotifyReleasedTransfer OCTET STRING (CONTAINING PDUSessionResourceNotifyReleasedTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceReleasedItemNot-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceReleasedItemNot-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceReleasedListPSAck ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceReleasedItemPSAck + +PDUSessionResourceReleasedItemPSAck ::= SEQUENCE { + pDUSessionID PDUSessionID, + pathSwitchRequestUnsuccessfulTransfer OCTET STRING (CONTAINING PathSwitchRequestUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceReleasedItemPSAck-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceReleasedItemPSAck-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceReleasedListPSFail ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceReleasedItemPSFail + +PDUSessionResourceReleasedItemPSFail ::= SEQUENCE { + pDUSessionID PDUSessionID, + pathSwitchRequestUnsuccessfulTransfer OCTET STRING (CONTAINING PathSwitchRequestUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceReleasedItemPSFail-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceReleasedItemPSFail-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceReleasedListRelRes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceReleasedItemRelRes + +PDUSessionResourceReleasedItemRelRes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceReleaseResponseTransfer OCTET STRING (CONTAINING PDUSessionResourceReleaseResponseTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceReleasedItemRelRes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceReleasedItemRelRes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceReleaseResponseTransfer ::= SEQUENCE { + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceReleaseResponseTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceReleaseResponseTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-SecondaryRATUsageInformation CRITICALITY ignore EXTENSION SecondaryRATUsageInformation PRESENCE optional }, + ... +} + +PDUSessionResourceSecondaryRATUsageList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSecondaryRATUsageItem + +PDUSessionResourceSecondaryRATUsageItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + secondaryRATDataUsageReportTransfer OCTET STRING (CONTAINING SecondaryRATDataUsageReportTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSecondaryRATUsageItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSecondaryRATUsageItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupListCxtReq ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSetupItemCxtReq + +PDUSessionResourceSetupItemCxtReq ::= SEQUENCE { + pDUSessionID PDUSessionID, + nAS-PDU NAS-PDU OPTIONAL, + s-NSSAI S-NSSAI, + pDUSessionResourceSetupRequestTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupRequestTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupItemCxtReq-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupItemCxtReq-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupListCxtRes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSetupItemCxtRes + +PDUSessionResourceSetupItemCxtRes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceSetupResponseTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupResponseTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupItemCxtRes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupItemCxtRes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupListHOReq ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSetupItemHOReq + +PDUSessionResourceSetupItemHOReq ::= SEQUENCE { + pDUSessionID PDUSessionID, + s-NSSAI S-NSSAI, + handoverRequestTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupRequestTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupItemHOReq-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupItemHOReq-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupListSUReq ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSetupItemSUReq + +PDUSessionResourceSetupItemSUReq ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionNAS-PDU NAS-PDU OPTIONAL, + s-NSSAI S-NSSAI, + pDUSessionResourceSetupRequestTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupRequestTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupItemSUReq-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupItemSUReq-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupListSURes ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSetupItemSURes + +PDUSessionResourceSetupItemSURes ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceSetupResponseTransfer OCTET STRING (CONTAINING PDUSessionResourceSetupResponseTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupItemSURes-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupItemSURes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupRequestTransfer ::= SEQUENCE { + protocolIEs ProtocolIE-Container { {PDUSessionResourceSetupRequestTransferIEs} }, + ... +} + +PDUSessionResourceSetupRequestTransferIEs NGAP-PROTOCOL-IES ::= { + { ID id-PDUSessionAggregateMaximumBitRate CRITICALITY reject TYPE PDUSessionAggregateMaximumBitRate PRESENCE optional }| + { ID id-UL-NGU-UP-TNLInformation CRITICALITY reject TYPE UPTransportLayerInformation PRESENCE mandatory }| + { ID id-AdditionalUL-NGU-UP-TNLInformation CRITICALITY reject TYPE UPTransportLayerInformationList PRESENCE optional }| + { ID id-DataForwardingNotPossible CRITICALITY reject TYPE DataForwardingNotPossible PRESENCE optional }| + { ID id-PDUSessionType CRITICALITY reject TYPE PDUSessionType PRESENCE mandatory }| + { ID id-SecurityIndication CRITICALITY reject TYPE SecurityIndication PRESENCE optional }| + { ID id-NetworkInstance CRITICALITY reject TYPE NetworkInstance PRESENCE optional }| + { ID id-QosFlowSetupRequestList CRITICALITY reject TYPE QosFlowSetupRequestList PRESENCE mandatory }| + { ID id-CommonNetworkInstance CRITICALITY ignore TYPE CommonNetworkInstance PRESENCE optional }, + ... +} + +PDUSessionResourceSetupResponseTransfer ::= SEQUENCE { + dLQosFlowPerTNLInformation QosFlowPerTNLInformation, + additionalDLQosFlowPerTNLInformation QosFlowPerTNLInformationList OPTIONAL, + securityResult SecurityResult OPTIONAL, + qosFlowFailedToSetupList QosFlowListWithCause OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupResponseTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupResponseTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSetupUnsuccessfulTransfer ::= SEQUENCE { + cause Cause, + criticalityDiagnostics CriticalityDiagnostics OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceSetupUnsuccessfulTransfer-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSetupUnsuccessfulTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceSwitchedList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceSwitchedItem + +PDUSessionResourceSwitchedItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + pathSwitchRequestAcknowledgeTransfer OCTET STRING (CONTAINING PathSwitchRequestAcknowledgeTransfer), + iE-Extensions ProtocolExtensionContainer { { PDUSessionResourceSwitchedItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceSwitchedItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceToBeSwitchedDLList ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceToBeSwitchedDLItem + +PDUSessionResourceToBeSwitchedDLItem ::= SEQUENCE { + pDUSessionID PDUSessionID, + pathSwitchRequestTransfer OCTET STRING (CONTAINING PathSwitchRequestTransfer), + iE-Extensions ProtocolExtensionContainer { { PDUSessionResourceToBeSwitchedDLItem-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceToBeSwitchedDLItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceToReleaseListHOCmd ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceToReleaseItemHOCmd + +PDUSessionResourceToReleaseItemHOCmd ::= SEQUENCE { + pDUSessionID PDUSessionID, + handoverPreparationUnsuccessfulTransfer OCTET STRING (CONTAINING HandoverPreparationUnsuccessfulTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceToReleaseItemHOCmd-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceToReleaseItemHOCmd-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PDUSessionResourceToReleaseListRelCmd ::= SEQUENCE (SIZE(1..maxnoofPDUSessions)) OF PDUSessionResourceToReleaseItemRelCmd + +PDUSessionResourceToReleaseItemRelCmd ::= SEQUENCE { + pDUSessionID PDUSessionID, + pDUSessionResourceReleaseCommandTransfer OCTET STRING (CONTAINING PDUSessionResourceReleaseCommandTransfer), + iE-Extensions ProtocolExtensionContainer { {PDUSessionResourceToReleaseItemRelCmd-ExtIEs} } OPTIONAL, + ... +} + +PDUSessionResourceToReleaseItemRelCmd-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} +PDUSessionType ::= ENUMERATED { + ipv4, + ipv6, + ipv4v6, + ethernet, + unstructured, + ... +} + +PDUSessionUsageReport ::= SEQUENCE { + rATType ENUMERATED {nr, eutra, ...}, + pDUSessionTimedReportList VolumeTimedReportList, + iE-Extensions ProtocolExtensionContainer { {PDUSessionUsageReport-ExtIEs} } OPTIONAL, +... +} + +PDUSessionUsageReport-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PeriodicRegistrationUpdateTimer ::= BIT STRING (SIZE(8)) + +PLMNIdentity ::= OCTET STRING (SIZE(3)) + +PLMNSupportList ::= SEQUENCE (SIZE(1..maxnoofPLMNs)) OF PLMNSupportItem + +PLMNSupportItem ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + sliceSupportList SliceSupportList, + iE-Extensions ProtocolExtensionContainer { {PLMNSupportItem-ExtIEs} } OPTIONAL, + ... +} + +PLMNSupportItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +PortNumber ::= OCTET STRING (SIZE(2)) + +Pre-emptionCapability ::= ENUMERATED { + shall-not-trigger-pre-emption, + may-trigger-pre-emption, + ... +} + +Pre-emptionVulnerability ::= ENUMERATED { + not-pre-emptable, + pre-emptable, + ... +} + +PriorityLevelARP ::= INTEGER (1..15) + +PriorityLevelQos ::= INTEGER (1..127, ...) + +PWSFailedCellIDList ::= CHOICE { + eUTRA-CGI-PWSFailedList EUTRA-CGIList, + nR-CGI-PWSFailedList NR-CGIList, + choice-Extensions ProtocolIE-SingleContainer { {PWSFailedCellIDList-ExtIEs} } +} + +PWSFailedCellIDList-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +-- Q + +QosCharacteristics ::= CHOICE { + nonDynamic5QI NonDynamic5QIDescriptor, + dynamic5QI Dynamic5QIDescriptor, + choice-Extensions ProtocolIE-SingleContainer { {QosCharacteristics-ExtIEs} } +} + +QosCharacteristics-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +QosFlowAcceptedList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowAcceptedItem + +QosFlowAcceptedItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + iE-Extensions ProtocolExtensionContainer { {QosFlowAcceptedItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowAcceptedItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowAddOrModifyRequestList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowAddOrModifyRequestItem + +QosFlowAddOrModifyRequestItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + qosFlowLevelQosParameters QosFlowLevelQosParameters OPTIONAL, + e-RAB-ID E-RAB-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {QosFlowAddOrModifyRequestItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowAddOrModifyRequestItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowAddOrModifyResponseList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowAddOrModifyResponseItem + +QosFlowAddOrModifyResponseItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + iE-Extensions ProtocolExtensionContainer { {QosFlowAddOrModifyResponseItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowAddOrModifyResponseItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowIdentifier ::= INTEGER (0..63, ...) + +QosFlowInformationList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowInformationItem + +QosFlowInformationItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + dLForwarding DLForwarding OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {QosFlowInformationItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowInformationItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + {ID id-ULForwarding CRITICALITY reject EXTENSION ULForwarding PRESENCE optional}, + ... +} + +QosFlowLevelQosParameters ::= SEQUENCE { + qosCharacteristics QosCharacteristics, + allocationAndRetentionPriority AllocationAndRetentionPriority, + gBR-QosInformation GBR-QosInformation OPTIONAL, + reflectiveQosAttribute ReflectiveQosAttribute OPTIONAL, + additionalQosFlowInformation AdditionalQosFlowInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {QosFlowLevelQosParameters-ExtIEs} } OPTIONAL, + ... +} + +QosFlowLevelQosParameters-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowListWithCause ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowWithCauseItem + +QosFlowWithCauseItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + cause Cause, + iE-Extensions ProtocolExtensionContainer { {QosFlowWithCauseItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowWithCauseItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowModifyConfirmList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowModifyConfirmItem + +QosFlowModifyConfirmItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + iE-Extensions ProtocolExtensionContainer { {QosFlowModifyConfirmItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowModifyConfirmItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowNotifyList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowNotifyItem + +QosFlowNotifyItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + notificationCause NotificationCause, + iE-Extensions ProtocolExtensionContainer { {QosFlowNotifyItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowNotifyItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowPerTNLInformation ::= SEQUENCE { + uPTransportLayerInformation UPTransportLayerInformation, + associatedQosFlowList AssociatedQosFlowList, + iE-Extensions ProtocolExtensionContainer { { QosFlowPerTNLInformation-ExtIEs} } OPTIONAL, + ... +} + +QosFlowPerTNLInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowPerTNLInformationList ::= SEQUENCE (SIZE(1..maxnoofMultiConnectivityMinusOne)) OF QosFlowPerTNLInformationItem + +QosFlowPerTNLInformationItem ::= SEQUENCE { + qosFlowPerTNLInformation QosFlowPerTNLInformation, + iE-Extensions ProtocolExtensionContainer { { QosFlowPerTNLInformationItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowPerTNLInformationItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowSetupRequestList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowSetupRequestItem + +QosFlowSetupRequestItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + qosFlowLevelQosParameters QosFlowLevelQosParameters, + e-RAB-ID E-RAB-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {QosFlowSetupRequestItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowSetupRequestItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowListWithDataForwarding ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowItemWithDataForwarding + +QosFlowItemWithDataForwarding ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + dataForwardingAccepted DataForwardingAccepted OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {QosFlowItemWithDataForwarding-ExtIEs} } OPTIONAL, + ... +} + +QosFlowItemWithDataForwarding-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowSetupResponseListSURes ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowSetupResponseItemSURes + +QosFlowSetupResponseItemSURes ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + iE-Extensions ProtocolExtensionContainer { {QosFlowSetupResponseItemSURes-ExtIEs} } OPTIONAL, + ... +} + +QosFlowSetupResponseItemSURes-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QosFlowToBeForwardedList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QosFlowToBeForwardedItem + +QosFlowToBeForwardedItem ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + iE-Extensions ProtocolExtensionContainer { {QosFlowToBeForwardedItem-ExtIEs} } OPTIONAL, + ... +} + +QosFlowToBeForwardedItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +QoSFlowsUsageReportList ::= SEQUENCE (SIZE(1..maxnoofQosFlows)) OF QoSFlowsUsageReport-Item + +QoSFlowsUsageReport-Item ::= SEQUENCE { + qosFlowIdentifier QosFlowIdentifier, + rATType ENUMERATED {nr, eutra, ...}, + qoSFlowsTimedReportList VolumeTimedReportList, + iE-Extensions ProtocolExtensionContainer { {QoSFlowsUsageReport-Item-ExtIEs} } OPTIONAL, +... +} + +QoSFlowsUsageReport-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- R + +RANNodeName ::= PrintableString (SIZE(1..150, ...)) + +RANPagingPriority ::= INTEGER (1..256) + +RANStatusTransfer-TransparentContainer ::= SEQUENCE { + dRBsSubjectToStatusTransferList DRBsSubjectToStatusTransferList, + iE-Extensions ProtocolExtensionContainer { {RANStatusTransfer-TransparentContainer-ExtIEs} } OPTIONAL, + ... +} + +RANStatusTransfer-TransparentContainer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +RAN-UE-NGAP-ID ::= INTEGER (0..4294967295) + +RATRestrictions ::= SEQUENCE (SIZE(1..maxnoofEPLMNsPlusOne)) OF RATRestrictions-Item + +RATRestrictions-Item ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + rATRestrictionInformation RATRestrictionInformation, + iE-Extensions ProtocolExtensionContainer { {RATRestrictions-Item-ExtIEs} } OPTIONAL, + ... +} + +RATRestrictions-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +RATRestrictionInformation ::= BIT STRING (SIZE(8, ...)) + +RecommendedCellsForPaging ::= SEQUENCE { + recommendedCellList RecommendedCellList, + iE-Extensions ProtocolExtensionContainer { {RecommendedCellsForPaging-ExtIEs} } OPTIONAL, + ... +} + +RecommendedCellsForPaging-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +RecommendedCellList ::= SEQUENCE (SIZE(1..maxnoofRecommendedCells)) OF RecommendedCellItem + +RecommendedCellItem ::= SEQUENCE { + nGRAN-CGI NGRAN-CGI, + timeStayedInCell INTEGER (0..4095) OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {RecommendedCellItem-ExtIEs} } OPTIONAL, + ... +} + +RecommendedCellItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +RecommendedRANNodesForPaging ::= SEQUENCE { + recommendedRANNodeList RecommendedRANNodeList, + iE-Extensions ProtocolExtensionContainer { {RecommendedRANNodesForPaging-ExtIEs} } OPTIONAL, + ... +} + +RecommendedRANNodesForPaging-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +RecommendedRANNodeList::= SEQUENCE (SIZE(1..maxnoofRecommendedRANNodes)) OF RecommendedRANNodeItem + +RecommendedRANNodeItem ::= SEQUENCE { + aMFPagingTarget AMFPagingTarget, + iE-Extensions ProtocolExtensionContainer { {RecommendedRANNodeItem-ExtIEs} } OPTIONAL, + ... +} + +RecommendedRANNodeItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +RedirectionVoiceFallback ::= ENUMERATED { + possible, + not-possible, + ... +} + +ReflectiveQosAttribute ::= ENUMERATED { + subject-to, + ... +} + +ReferenceID ::= INTEGER (1..64, ...) + +RelativeAMFCapacity ::= INTEGER (0..255) + +ReportArea ::= ENUMERATED { + cell, + ... +} + +RepetitionPeriod ::= INTEGER (0..131071) + +ResetAll ::= ENUMERATED { + reset-all, + ... +} + +ResetType ::= CHOICE { + nG-Interface ResetAll, + partOfNG-Interface UE-associatedLogicalNG-connectionList, + choice-Extensions ProtocolIE-SingleContainer { {ResetType-ExtIEs} } +} + +ResetType-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +RoutingID ::= OCTET STRING + +RRCContainer ::= OCTET STRING + +RRCEstablishmentCause ::= ENUMERATED { + emergency, + highPriorityAccess, + mt-Access, + mo-Signalling, + mo-Data, + mo-VoiceCall, + mo-VideoCall, + mo-SMS, + mps-PriorityAccess, + mcs-PriorityAccess, + ..., + notAvailable +} + +RRCInactiveTransitionReportRequest ::= ENUMERATED { + subsequent-state-transition-report, + single-rrc-connected-state-report, + cancel-report, + ... +} + +RRCState ::= ENUMERATED { + inactive, + connected, + ... +} + +-- S + +SCTP-TLAs ::= SEQUENCE (SIZE(1..maxnoofXnTLAs)) OF TransportLayerAddress + +SD ::= OCTET STRING (SIZE(3)) + +SecondaryRATUsageInformation ::= SEQUENCE { + pDUSessionUsageReport PDUSessionUsageReport OPTIONAL, + qosFlowsUsageReportList QoSFlowsUsageReportList OPTIONAL, + iE-Extension ProtocolExtensionContainer { {SecondaryRATUsageInformation-ExtIEs} } OPTIONAL, + ... +} + +SecondaryRATUsageInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SecondaryRATDataUsageReportTransfer ::= SEQUENCE { + secondaryRATUsageInformation SecondaryRATUsageInformation OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {SecondaryRATDataUsageReportTransfer-ExtIEs} } OPTIONAL, + ... +} + +SecondaryRATDataUsageReportTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SecurityContext ::= SEQUENCE { + nextHopChainingCount NextHopChainingCount, + nextHopNH SecurityKey, + iE-Extensions ProtocolExtensionContainer { {SecurityContext-ExtIEs} } OPTIONAL, + ... +} + +SecurityContext-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SecurityIndication ::= SEQUENCE { + integrityProtectionIndication IntegrityProtectionIndication, + confidentialityProtectionIndication ConfidentialityProtectionIndication, + maximumIntegrityProtectedDataRate-UL MaximumIntegrityProtectedDataRate OPTIONAL, +-- The above IE shall be present if integrity protection is required or preferred + iE-Extensions ProtocolExtensionContainer { {SecurityIndication-ExtIEs} } OPTIONAL, + ... +} + +SecurityIndication-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-MaximumIntegrityProtectedDataRate-DL CRITICALITY ignore EXTENSION MaximumIntegrityProtectedDataRate PRESENCE optional }, + ... +} + +SecurityKey ::= BIT STRING (SIZE(256)) + +SecurityResult ::= SEQUENCE { + integrityProtectionResult IntegrityProtectionResult, + confidentialityProtectionResult ConfidentialityProtectionResult, + iE-Extensions ProtocolExtensionContainer { {SecurityResult-ExtIEs} } OPTIONAL, + ... +} + +SecurityResult-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SerialNumber ::= BIT STRING (SIZE(16)) + +ServedGUAMIList ::= SEQUENCE (SIZE(1..maxnoofServedGUAMIs)) OF ServedGUAMIItem + +ServedGUAMIItem ::= SEQUENCE { + gUAMI GUAMI, + backupAMFName AMFName OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {ServedGUAMIItem-ExtIEs} } OPTIONAL, + ... +} + +ServedGUAMIItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +ServiceAreaInformation ::= SEQUENCE (SIZE(1.. maxnoofEPLMNsPlusOne)) OF ServiceAreaInformation-Item + +ServiceAreaInformation-Item ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + allowedTACs AllowedTACs OPTIONAL, + notAllowedTACs NotAllowedTACs OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {ServiceAreaInformation-Item-ExtIEs} } OPTIONAL, + ... +} + +ServiceAreaInformation-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + + +SliceOverloadList ::= SEQUENCE (SIZE(1..maxnoofSliceItems)) OF SliceOverloadItem + +SliceOverloadItem ::= SEQUENCE { + s-NSSAI S-NSSAI, + iE-Extensions ProtocolExtensionContainer { {SliceOverloadItem-ExtIEs} } OPTIONAL, + ... +} + +SliceOverloadItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SliceSupportList ::= SEQUENCE (SIZE(1..maxnoofSliceItems)) OF SliceSupportItem + +SliceSupportItem ::= SEQUENCE { + s-NSSAI S-NSSAI, + iE-Extensions ProtocolExtensionContainer { {SliceSupportItem-ExtIEs} } OPTIONAL, + ... +} + +SliceSupportItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +S-NSSAI ::= SEQUENCE { + sST SST, + sD SD OPTIONAL, + iE-Extensions ProtocolExtensionContainer { { S-NSSAI-ExtIEs} } OPTIONAL, + ... +} + +S-NSSAI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SONConfigurationTransfer ::= SEQUENCE { + targetRANNodeID TargetRANNodeID, + sourceRANNodeID SourceRANNodeID, + sONInformation SONInformation, + xnTNLConfigurationInfo XnTNLConfigurationInfo OPTIONAL, +-- The above IE shall be present if the SON Information IE contains the SON Information Request IE set to ¡°Xn TNL Configuration Info¡± + iE-Extensions ProtocolExtensionContainer { {SONConfigurationTransfer-ExtIEs} } OPTIONAL, + ... +} + +SONConfigurationTransfer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SONInformation ::= CHOICE { + sONInformationRequest SONInformationRequest, + sONInformationReply SONInformationReply, + choice-Extensions ProtocolIE-SingleContainer { {SONInformation-ExtIEs} } +} + +SONInformation-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +SONInformationReply ::= SEQUENCE { + xnTNLConfigurationInfo XnTNLConfigurationInfo OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {SONInformationReply-ExtIEs} } OPTIONAL, + ... +} + +SONInformationReply-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SONInformationRequest ::= ENUMERATED { + xn-TNL-configuration-info, + ... +} + +SourceNGRANNode-ToTargetNGRANNode-TransparentContainer ::= SEQUENCE { + rRCContainer RRCContainer, + pDUSessionResourceInformationList PDUSessionResourceInformationList OPTIONAL, + e-RABInformationList E-RABInformationList OPTIONAL, + targetCell-ID NGRAN-CGI, + indexToRFSP IndexToRFSP OPTIONAL, + uEHistoryInformation UEHistoryInformation, + iE-Extensions ProtocolExtensionContainer { {SourceNGRANNode-ToTargetNGRANNode-TransparentContainer-ExtIEs} } OPTIONAL, + ... +} + +SourceNGRANNode-ToTargetNGRANNode-TransparentContainer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SourceOfUEActivityBehaviourInformation ::= ENUMERATED { + subscription-information, + statistics, + ... +} + +SourceRANNodeID ::= SEQUENCE { + globalRANNodeID GlobalRANNodeID, + selectedTAI TAI, + iE-Extensions ProtocolExtensionContainer { {SourceRANNodeID-ExtIEs} } OPTIONAL, + ... +} + +SourceRANNodeID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +SourceToTarget-TransparentContainer ::= OCTET STRING +-- This IE includes a transparent container from the source RAN node to the target RAN node. +-- The octets of the OCTET STRING are encoded according to the specifications of the target system. + +SourceToTarget-AMFInformationReroute ::= SEQUENCE { +configuredNSSAI ConfiguredNSSAI OPTIONAL, +rejectedNSSAIinPLMN RejectedNSSAIinPLMN OPTIONAL, +rejectedNSSAIinTA RejectedNSSAIinTA OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {SourceToTarget-AMFInformationReroute-ExtIEs} } OPTIONAL, + ... +} + +SourceToTarget-AMFInformationReroute-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- This IE includes information from the source Core node to the target Core node for reroute information provide by NSSF. +-- The octets of the OCTET STRING are encoded according to the specifications of the Core network. + + +ConfiguredNSSAI ::= OCTET STRING (SIZE(128)) + +RejectedNSSAIinPLMN ::= OCTET STRING (SIZE(32)) + +RejectedNSSAIinTA ::= OCTET STRING (SIZE(32)) + +SST ::= OCTET STRING (SIZE(1)) + +SupportedTAList ::= SEQUENCE (SIZE(1..maxnoofTACs)) OF SupportedTAItem + +SupportedTAItem ::= SEQUENCE { + tAC TAC, + broadcastPLMNList BroadcastPLMNList, + iE-Extensions ProtocolExtensionContainer { {SupportedTAItem-ExtIEs} } OPTIONAL, + ... +} + +SupportedTAItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- T + +TAC ::= OCTET STRING (SIZE(3)) + +TAI ::= SEQUENCE { + pLMNIdentity PLMNIdentity, + tAC TAC, + iE-Extensions ProtocolExtensionContainer { {TAI-ExtIEs} } OPTIONAL, + ... +} + +TAI-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAIBroadcastEUTRA ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAIBroadcastEUTRA-Item + +TAIBroadcastEUTRA-Item ::= SEQUENCE { + tAI TAI, + completedCellsInTAI-EUTRA CompletedCellsInTAI-EUTRA, + iE-Extensions ProtocolExtensionContainer { {TAIBroadcastEUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +TAIBroadcastEUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAIBroadcastNR ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAIBroadcastNR-Item + +TAIBroadcastNR-Item ::= SEQUENCE { + tAI TAI, + completedCellsInTAI-NR CompletedCellsInTAI-NR, + iE-Extensions ProtocolExtensionContainer { {TAIBroadcastNR-Item-ExtIEs} } OPTIONAL, + ... +} + +TAIBroadcastNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAICancelledEUTRA ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAICancelledEUTRA-Item + +TAICancelledEUTRA-Item ::= SEQUENCE { + tAI TAI, + cancelledCellsInTAI-EUTRA CancelledCellsInTAI-EUTRA, + iE-Extensions ProtocolExtensionContainer { {TAICancelledEUTRA-Item-ExtIEs} } OPTIONAL, + ... +} + +TAICancelledEUTRA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAICancelledNR ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAICancelledNR-Item + +TAICancelledNR-Item ::= SEQUENCE { + tAI TAI, + cancelledCellsInTAI-NR CancelledCellsInTAI-NR, + iE-Extensions ProtocolExtensionContainer { {TAICancelledNR-Item-ExtIEs} } OPTIONAL, + ... +} + +TAICancelledNR-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAIListForInactive ::= SEQUENCE (SIZE(1..maxnoofTAIforInactive)) OF TAIListForInactiveItem + +TAIListForInactiveItem ::= SEQUENCE { + tAI TAI, + iE-Extensions ProtocolExtensionContainer { {TAIListForInactiveItem-ExtIEs} } OPTIONAL, + ... +} + +TAIListForInactiveItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAIListForPaging ::= SEQUENCE (SIZE(1..maxnoofTAIforPaging)) OF TAIListForPagingItem + +TAIListForPagingItem ::= SEQUENCE { + tAI TAI, + iE-Extensions ProtocolExtensionContainer { {TAIListForPagingItem-ExtIEs} } OPTIONAL, + ... +} + +TAIListForPagingItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TAIListForRestart ::= SEQUENCE (SIZE(1..maxnoofTAIforRestart)) OF TAI + +TAIListForWarning ::= SEQUENCE (SIZE(1..maxnoofTAIforWarning)) OF TAI + +TargeteNB-ID ::= SEQUENCE { + globalENB-ID GlobalNgENB-ID, + selected-EPS-TAI EPS-TAI, + iE-Extensions ProtocolExtensionContainer { {TargeteNB-ID-ExtIEs} } OPTIONAL, + ... +} + +TargeteNB-ID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TargetID ::= CHOICE { + targetRANNodeID TargetRANNodeID, + targeteNB-ID TargeteNB-ID, + choice-Extensions ProtocolIE-SingleContainer { {TargetID-ExtIEs} } +} + +TargetID-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +TargetNGRANNode-ToSourceNGRANNode-TransparentContainer ::= SEQUENCE { + rRCContainer RRCContainer, + iE-Extensions ProtocolExtensionContainer { {TargetNGRANNode-ToSourceNGRANNode-TransparentContainer-ExtIEs} } OPTIONAL, + ... +} + +TargetNGRANNode-ToSourceNGRANNode-TransparentContainer-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TargetRANNodeID ::= SEQUENCE { + globalRANNodeID GlobalRANNodeID, + selectedTAI TAI, + iE-Extensions ProtocolExtensionContainer { {TargetRANNodeID-ExtIEs} } OPTIONAL, + ... +} + +TargetRANNodeID-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TargetToSource-TransparentContainer ::= OCTET STRING +-- This IE includes a transparent container from the target RAN node to the source RAN node. +-- The octets of the OCTET STRING are encoded according to the specifications of the target system. + +TimerApproachForGUAMIRemoval ::= ENUMERATED { + apply-timer, + ... +} + +TimeStamp ::= OCTET STRING (SIZE(4)) + +TimeToWait ::= ENUMERATED {v1s, v2s, v5s, v10s, v20s, v60s, ...} + +TimeUEStayedInCell ::= INTEGER (0..4095) + +TimeUEStayedInCellEnhancedGranularity ::= INTEGER (0..40950) + +TNLAddressWeightFactor ::= INTEGER (0..255) + +TNLAssociationList ::= SEQUENCE (SIZE(1..maxnoofTNLAssociations)) OF TNLAssociationItem + +TNLAssociationItem ::= SEQUENCE { + tNLAssociationAddress CPTransportLayerInformation, + cause Cause, + iE-Extensions ProtocolExtensionContainer { {TNLAssociationItem-ExtIEs} } OPTIONAL, + ... +} + +TNLAssociationItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TNLAssociationUsage ::= ENUMERATED { + ue, + non-ue, + both, + ... +} + +TraceActivation ::= SEQUENCE { + nGRANTraceID NGRANTraceID, + interfacesToTrace InterfacesToTrace, + traceDepth TraceDepth, + traceCollectionEntityIPAddress TransportLayerAddress, + iE-Extensions ProtocolExtensionContainer { {TraceActivation-ExtIEs} } OPTIONAL, + ... +} + +TraceActivation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +TraceDepth ::= ENUMERATED { + minimum, + medium, + maximum, + minimumWithoutVendorSpecificExtension, + mediumWithoutVendorSpecificExtension, + maximumWithoutVendorSpecificExtension, + ... +} + +TrafficLoadReductionIndication ::= INTEGER (1..99) + +TransportLayerAddress ::= BIT STRING (SIZE(1..160, ...)) + +TypeOfError ::= ENUMERATED { + not-understood, + missing, + ... +} + +-- U + +UEAggregateMaximumBitRate ::= SEQUENCE { + uEAggregateMaximumBitRateDL BitRate, + uEAggregateMaximumBitRateUL BitRate, + iE-Extensions ProtocolExtensionContainer { {UEAggregateMaximumBitRate-ExtIEs} } OPTIONAL, + ... +} + +UEAggregateMaximumBitRate-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UE-associatedLogicalNG-connectionList ::= SEQUENCE (SIZE(1..maxnoofNGConnectionsToReset)) OF UE-associatedLogicalNG-connectionItem + +UE-associatedLogicalNG-connectionItem ::= SEQUENCE { + aMF-UE-NGAP-ID AMF-UE-NGAP-ID OPTIONAL, + rAN-UE-NGAP-ID RAN-UE-NGAP-ID OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {UE-associatedLogicalNG-connectionItem-ExtIEs} } OPTIONAL, + ... +} + +UE-associatedLogicalNG-connectionItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ...} + +UEContextRequest ::= ENUMERATED {requested, ...} + +UEHistoryInformation ::= SEQUENCE (SIZE(1..maxnoofCellsinUEHistoryInfo)) OF LastVisitedCellItem + +UEIdentityIndexValue ::= CHOICE { + indexLength10 BIT STRING (SIZE(10)), + choice-Extensions ProtocolIE-SingleContainer { {UEIdentityIndexValue-ExtIEs} } +} + +UEIdentityIndexValue-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +UE-NGAP-IDs ::= CHOICE { + uE-NGAP-ID-pair UE-NGAP-ID-pair, + aMF-UE-NGAP-ID AMF-UE-NGAP-ID, + choice-Extensions ProtocolIE-SingleContainer { {UE-NGAP-IDs-ExtIEs} } +} + +UE-NGAP-IDs-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +UE-NGAP-ID-pair ::= SEQUENCE{ + aMF-UE-NGAP-ID AMF-UE-NGAP-ID, + rAN-UE-NGAP-ID RAN-UE-NGAP-ID, + iE-Extensions ProtocolExtensionContainer { {UE-NGAP-ID-pair-ExtIEs} } OPTIONAL, + ... +} + +UE-NGAP-ID-pair-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UEPagingIdentity ::= CHOICE { + fiveG-S-TMSI FiveG-S-TMSI, + choice-Extensions ProtocolIE-SingleContainer { {UEPagingIdentity-ExtIEs} } + } + +UEPagingIdentity-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +UEPresence ::= ENUMERATED {in, out, unknown, ...} + +UEPresenceInAreaOfInterestList ::= SEQUENCE (SIZE(1..maxnoofAoI)) OF UEPresenceInAreaOfInterestItem + +UEPresenceInAreaOfInterestItem ::= SEQUENCE { + locationReportingReferenceID LocationReportingReferenceID, + uEPresence UEPresence, + iE-Extensions ProtocolExtensionContainer { {UEPresenceInAreaOfInterestItem-ExtIEs} } OPTIONAL, + ... +} + +UEPresenceInAreaOfInterestItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UERadioCapability ::= OCTET STRING + +UERadioCapabilityForPaging ::= SEQUENCE { + uERadioCapabilityForPagingOfNR UERadioCapabilityForPagingOfNR OPTIONAL, + uERadioCapabilityForPagingOfEUTRA UERadioCapabilityForPagingOfEUTRA OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {UERadioCapabilityForPaging-ExtIEs} } OPTIONAL, + ... +} + +UERadioCapabilityForPaging-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UERadioCapabilityForPagingOfNR ::= OCTET STRING + +UERadioCapabilityForPagingOfEUTRA ::= OCTET STRING + +UERetentionInformation ::= ENUMERATED { + ues-retained, + ... +} + +UESecurityCapabilities ::= SEQUENCE { + nRencryptionAlgorithms NRencryptionAlgorithms, + nRintegrityProtectionAlgorithms NRintegrityProtectionAlgorithms, + eUTRAencryptionAlgorithms EUTRAencryptionAlgorithms, + eUTRAintegrityProtectionAlgorithms EUTRAintegrityProtectionAlgorithms, + + iE-Extensions ProtocolExtensionContainer { {UESecurityCapabilities-ExtIEs} } OPTIONAL, + ... +} + +UESecurityCapabilities-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UL-NGU-UP-TNLModifyList ::= SEQUENCE (SIZE(1..maxnoofMultiConnectivity)) OF UL-NGU-UP-TNLModifyItem + +UL-NGU-UP-TNLModifyItem ::= SEQUENCE { + uL-NGU-UP-TNLInformation UPTransportLayerInformation, + dL-NGU-UP-TNLInformation UPTransportLayerInformation, + iE-Extensions ProtocolExtensionContainer { {UL-NGU-UP-TNLModifyItem-ExtIEs} } OPTIONAL, + ... +} + +UL-NGU-UP-TNLModifyItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UnavailableGUAMIList ::= SEQUENCE (SIZE(1..maxnoofServedGUAMIs)) OF UnavailableGUAMIItem + +UnavailableGUAMIItem ::= SEQUENCE { + gUAMI GUAMI, + timerApproachForGUAMIRemoval TimerApproachForGUAMIRemoval OPTIONAL, + backupAMFName AMFName OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {UnavailableGUAMIItem-ExtIEs} } OPTIONAL, + ... +} + +UnavailableGUAMIItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +ULForwarding ::= ENUMERATED { + ul-forwarding-proposed, + ... +} + +UPTransportLayerInformation ::= CHOICE { + gTPTunnel GTPTunnel, + choice-Extensions ProtocolIE-SingleContainer { {UPTransportLayerInformation-ExtIEs} } +} + +UPTransportLayerInformation-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +UPTransportLayerInformationList ::= SEQUENCE (SIZE(1..maxnoofMultiConnectivityMinusOne)) OF UPTransportLayerInformationItem + +UPTransportLayerInformationItem ::= SEQUENCE { + nGU-UP-TNLInformation UPTransportLayerInformation, + iE-Extensions ProtocolExtensionContainer { {UPTransportLayerInformationItem-ExtIEs} } OPTIONAL, + ... +} + +UPTransportLayerInformationItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + + +UPTransportLayerInformationPairList ::= SEQUENCE (SIZE(1..maxnoofMultiConnectivityMinusOne)) OF UPTransportLayerInformationPairItem + +UPTransportLayerInformationPairItem ::= SEQUENCE { + uL-NGU-UP-TNLInformation UPTransportLayerInformation, + dL-NGU-UP-TNLInformation UPTransportLayerInformation, + iE-Extensions ProtocolExtensionContainer { {UPTransportLayerInformationPairItem-ExtIEs} } OPTIONAL, + ... +} + +UPTransportLayerInformationPairItem-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UserLocationInformation ::= CHOICE { + userLocationInformationEUTRA UserLocationInformationEUTRA, + userLocationInformationNR UserLocationInformationNR, + userLocationInformationN3IWF UserLocationInformationN3IWF, + choice-Extensions ProtocolIE-SingleContainer { {UserLocationInformation-ExtIEs} } +} + +UserLocationInformation-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +UserLocationInformationEUTRA ::= SEQUENCE { + eUTRA-CGI EUTRA-CGI, + tAI TAI, + timeStamp TimeStamp OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {UserLocationInformationEUTRA-ExtIEs} } OPTIONAL, + ... +} + +UserLocationInformationEUTRA-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-PSCellInformation CRITICALITY ignore EXTENSION NGRAN-CGI PRESENCE optional}, + ... +} + +UserLocationInformationN3IWF ::= SEQUENCE { + iPAddress TransportLayerAddress, + portNumber PortNumber, + iE-Extensions ProtocolExtensionContainer { {UserLocationInformationN3IWF-ExtIEs} } OPTIONAL, + ... +} + +UserLocationInformationN3IWF-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +UserLocationInformationNR ::= SEQUENCE { + nR-CGI NR-CGI, + tAI TAI, + timeStamp TimeStamp OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {UserLocationInformationNR-ExtIEs} } OPTIONAL, + ... +} + +UserLocationInformationNR-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-PSCellInformation CRITICALITY ignore EXTENSION NGRAN-CGI PRESENCE optional}, + ... +} + +UserPlaneSecurityInformation ::= SEQUENCE { + securityResult SecurityResult, + securityIndication SecurityIndication, + iE-Extensions ProtocolExtensionContainer { {UserPlaneSecurityInformation-ExtIEs} } OPTIONAL, + ... +} + +UserPlaneSecurityInformation-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- V + +VolumeTimedReportList ::= SEQUENCE (SIZE(1..maxnoofTimePeriods)) OF VolumeTimedReport-Item + +VolumeTimedReport-Item ::= SEQUENCE { + startTimeStamp OCTET STRING (SIZE(4)), + endTimeStamp OCTET STRING (SIZE(4)), + usageCountUL INTEGER (0..18446744073709551615), + usageCountDL INTEGER (0..18446744073709551615), + iE-Extensions ProtocolExtensionContainer { {VolumeTimedReport-Item-ExtIEs} } OPTIONAL, +... +} + +VolumeTimedReport-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- W + +WarningAreaCoordinates ::= OCTET STRING (SIZE(1..1024)) + +WarningAreaList ::= CHOICE { + eUTRA-CGIListForWarning EUTRA-CGIListForWarning, + nR-CGIListForWarning NR-CGIListForWarning, + tAIListForWarning TAIListForWarning, + emergencyAreaIDList EmergencyAreaIDList, + choice-Extensions ProtocolIE-SingleContainer { {WarningAreaList-ExtIEs} } +} + +WarningAreaList-ExtIEs NGAP-PROTOCOL-IES ::= { + ... +} + +WarningMessageContents ::= OCTET STRING (SIZE(1..9600)) + +WarningSecurityInfo ::= OCTET STRING (SIZE(50)) + +WarningType ::= OCTET STRING (SIZE(2)) + +-- X + +XnExtTLAs ::= SEQUENCE (SIZE(1..maxnoofXnExtTLAs)) OF XnExtTLA-Item + +XnExtTLA-Item ::= SEQUENCE { + iPsecTLA TransportLayerAddress OPTIONAL, + gTP-TLAs XnGTP-TLAs OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {XnExtTLA-Item-ExtIEs} } OPTIONAL, + ... +} + +XnExtTLA-Item-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + { ID id-SCTP-TLAs CRITICALITY ignore EXTENSION SCTP-TLAs PRESENCE optional }, + ... +} + +XnGTP-TLAs ::= SEQUENCE (SIZE(1..maxnoofXnGTP-TLAs)) OF TransportLayerAddress + +XnTLAs ::= SEQUENCE (SIZE(1..maxnoofXnTLAs)) OF TransportLayerAddress + +XnTNLConfigurationInfo ::= SEQUENCE { + xnTransportLayerAddresses XnTLAs, + xnExtendedTransportLayerAddresses XnExtTLAs OPTIONAL, + iE-Extensions ProtocolExtensionContainer { {XnTNLConfigurationInfo-ExtIEs} } OPTIONAL, + ... +} + +XnTNLConfigurationInfo-ExtIEs NGAP-PROTOCOL-EXTENSION ::= { + ... +} + +-- Y +-- Z + +END +-- ASN1STOP + +-- ASN1START +-- ************************************************************** +-- +-- Common definitions +-- +-- ************************************************************** + +NGAP-CommonDataTypes { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-CommonDataTypes (3) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +Criticality ::= ENUMERATED { reject, ignore, notify } + +Presence ::= ENUMERATED { optional, conditional, mandatory } + +PrivateIE-ID ::= CHOICE { + local INTEGER (0..65535), + global OBJECT IDENTIFIER +} + +ProcedureCode ::= INTEGER (0..255) + +ProtocolExtensionID ::= INTEGER (0..65535) + +ProtocolIE-ID ::= INTEGER (0..65535) + +TriggeringMessage ::= ENUMERATED { initiating-message, successful-outcome, unsuccessfull-outcome } + +END +-- ASN1STOP + +-- ASN1START +-- ************************************************************** +-- +-- Constant definitions +-- +-- ************************************************************** + +NGAP-Constants { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-Constants (4) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + ProcedureCode, + ProtocolIE-ID +FROM NGAP-CommonDataTypes; + + +-- ************************************************************** +-- +-- Elementary Procedures +-- +-- ************************************************************** + +id-AMFConfigurationUpdate ProcedureCode ::= 0 +id-AMFStatusIndication ProcedureCode ::= 1 +id-CellTrafficTrace ProcedureCode ::= 2 +id-DeactivateTrace ProcedureCode ::= 3 +id-DownlinkNASTransport ProcedureCode ::= 4 +id-DownlinkNonUEAssociatedNRPPaTransport ProcedureCode ::= 5 +id-DownlinkRANConfigurationTransfer ProcedureCode ::= 6 +id-DownlinkRANStatusTransfer ProcedureCode ::= 7 +id-DownlinkUEAssociatedNRPPaTransport ProcedureCode ::= 8 +id-ErrorIndication ProcedureCode ::= 9 +id-HandoverCancel ProcedureCode ::= 10 +id-HandoverNotification ProcedureCode ::= 11 +id-HandoverPreparation ProcedureCode ::= 12 +id-HandoverResourceAllocation ProcedureCode ::= 13 +id-InitialContextSetup ProcedureCode ::= 14 +id-InitialUEMessage ProcedureCode ::= 15 +id-LocationReportingControl ProcedureCode ::= 16 +id-LocationReportingFailureIndication ProcedureCode ::= 17 +id-LocationReport ProcedureCode ::= 18 +id-NASNonDeliveryIndication ProcedureCode ::= 19 +id-NGReset ProcedureCode ::= 20 +id-NGSetup ProcedureCode ::= 21 +id-OverloadStart ProcedureCode ::= 22 +id-OverloadStop ProcedureCode ::= 23 +id-Paging ProcedureCode ::= 24 +id-PathSwitchRequest ProcedureCode ::= 25 +id-PDUSessionResourceModify ProcedureCode ::= 26 +id-PDUSessionResourceModifyIndication ProcedureCode ::= 27 +id-PDUSessionResourceRelease ProcedureCode ::= 28 +id-PDUSessionResourceSetup ProcedureCode ::= 29 +id-PDUSessionResourceNotify ProcedureCode ::= 30 +id-PrivateMessage ProcedureCode ::= 31 +id-PWSCancel ProcedureCode ::= 32 +id-PWSFailureIndication ProcedureCode ::= 33 +id-PWSRestartIndication ProcedureCode ::= 34 +id-RANConfigurationUpdate ProcedureCode ::= 35 +id-RerouteNASRequest ProcedureCode ::= 36 +id-RRCInactiveTransitionReport ProcedureCode ::= 37 +id-TraceFailureIndication ProcedureCode ::= 38 +id-TraceStart ProcedureCode ::= 39 +id-UEContextModification ProcedureCode ::= 40 +id-UEContextRelease ProcedureCode ::= 41 +id-UEContextReleaseRequest ProcedureCode ::= 42 +id-UERadioCapabilityCheck ProcedureCode ::= 43 +id-UERadioCapabilityInfoIndication ProcedureCode ::= 44 +id-UETNLABindingRelease ProcedureCode ::= 45 +id-UplinkNASTransport ProcedureCode ::= 46 +id-UplinkNonUEAssociatedNRPPaTransport ProcedureCode ::= 47 +id-UplinkRANConfigurationTransfer ProcedureCode ::= 48 +id-UplinkRANStatusTransfer ProcedureCode ::= 49 +id-UplinkUEAssociatedNRPPaTransport ProcedureCode ::= 50 +id-WriteReplaceWarning ProcedureCode ::= 51 +id-SecondaryRATDataUsageReport ProcedureCode ::= 52 + +-- ************************************************************** +-- +-- Extension constants +-- +-- ************************************************************** + +maxPrivateIEs INTEGER ::= 65535 +maxProtocolExtensions INTEGER ::= 65535 +maxProtocolIEs INTEGER ::= 65535 + +-- ************************************************************** +-- +-- Lists +-- +-- ************************************************************** + + maxnoofAllowedAreas INTEGER ::= 16 + maxnoofAllowedS-NSSAIs INTEGER ::= 8 + maxnoofBPLMNs INTEGER ::= 12 + maxnoofCellIDforWarning INTEGER ::= 65535 + maxnoofCellinAoI INTEGER ::= 256 + maxnoofCellinEAI INTEGER ::= 65535 + maxnoofCellinTAI INTEGER ::= 65535 + maxnoofCellsingNB INTEGER ::= 16384 + maxnoofCellsinngeNB INTEGER ::= 256 + maxnoofCellsinUEHistoryInfo INTEGER ::= 16 + maxnoofCellsUEMovingTrajectory INTEGER ::= 16 + maxnoofDRBs INTEGER ::= 32 + maxnoofEmergencyAreaID INTEGER ::= 65535 + maxnoofEAIforRestart INTEGER ::= 256 + maxnoofEPLMNs INTEGER ::= 15 + maxnoofEPLMNsPlusOne INTEGER ::= 16 + maxnoofE-RABs INTEGER ::= 256 + maxnoofErrors INTEGER ::= 256 + maxnoofForbTACs INTEGER ::= 4096 + maxnoofMultiConnectivity INTEGER ::= 4 + maxnoofMultiConnectivityMinusOne INTEGER ::= 3 + maxnoofNGConnectionsToReset INTEGER ::= 65536 + maxnoofPDUSessions INTEGER ::= 256 + maxnoofPLMNs INTEGER ::= 12 + maxnoofQosFlows INTEGER ::= 64 + maxnoofRANNodeinAoI INTEGER ::= 64 + maxnoofRecommendedCells INTEGER ::= 16 + maxnoofRecommendedRANNodes INTEGER ::= 16 + maxnoofAoI INTEGER ::= 64 + maxnoofServedGUAMIs INTEGER ::= 256 + maxnoofSliceItems INTEGER ::= 1024 + maxnoofTACs INTEGER ::= 256 + maxnoofTAIforInactive INTEGER ::= 16 + maxnoofTAIforPaging INTEGER ::= 16 + maxnoofTAIforRestart INTEGER ::= 2048 + maxnoofTAIforWarning INTEGER ::= 65535 + maxnoofTAIinAoI INTEGER ::= 16 + maxnoofTimePeriods INTEGER ::= 2 + maxnoofTNLAssociations INTEGER ::= 32 + maxnoofXnExtTLAs INTEGER ::= 16 + maxnoofXnGTP-TLAs INTEGER ::= 16 + maxnoofXnTLAs INTEGER ::= 2 + +-- ************************************************************** +-- +-- IEs +-- +-- ************************************************************** + + id-AllowedNSSAI ProtocolIE-ID ::= 0 + id-AMFName ProtocolIE-ID ::= 1 + id-AMFOverloadResponse ProtocolIE-ID ::= 2 + id-AMFSetID ProtocolIE-ID ::= 3 + id-AMF-TNLAssociationFailedToSetupList ProtocolIE-ID ::= 4 + id-AMF-TNLAssociationSetupList ProtocolIE-ID ::= 5 + id-AMF-TNLAssociationToAddList ProtocolIE-ID ::= 6 + id-AMF-TNLAssociationToRemoveList ProtocolIE-ID ::= 7 + id-AMF-TNLAssociationToUpdateList ProtocolIE-ID ::= 8 + id-AMFTrafficLoadReductionIndication ProtocolIE-ID ::= 9 + id-AMF-UE-NGAP-ID ProtocolIE-ID ::= 10 + id-AssistanceDataForPaging ProtocolIE-ID ::= 11 + id-BroadcastCancelledAreaList ProtocolIE-ID ::= 12 + id-BroadcastCompletedAreaList ProtocolIE-ID ::= 13 + id-CancelAllWarningMessages ProtocolIE-ID ::= 14 + id-Cause ProtocolIE-ID ::= 15 + id-CellIDListForRestart ProtocolIE-ID ::= 16 + id-ConcurrentWarningMessageInd ProtocolIE-ID ::= 17 + id-CoreNetworkAssistanceInformationForInactive ProtocolIE-ID ::= 18 + id-CriticalityDiagnostics ProtocolIE-ID ::= 19 + id-DataCodingScheme ProtocolIE-ID ::= 20 + id-DefaultPagingDRX ProtocolIE-ID ::= 21 + id-DirectForwardingPathAvailability ProtocolIE-ID ::= 22 + id-EmergencyAreaIDListForRestart ProtocolIE-ID ::= 23 + id-EmergencyFallbackIndicator ProtocolIE-ID ::= 24 + id-EUTRA-CGI ProtocolIE-ID ::= 25 + id-FiveG-S-TMSI ProtocolIE-ID ::= 26 + id-GlobalRANNodeID ProtocolIE-ID ::= 27 + id-GUAMI ProtocolIE-ID ::= 28 + id-HandoverType ProtocolIE-ID ::= 29 + id-IMSVoiceSupportIndicator ProtocolIE-ID ::= 30 + id-IndexToRFSP ProtocolIE-ID ::= 31 + id-InfoOnRecommendedCellsAndRANNodesForPaging ProtocolIE-ID ::= 32 + id-LocationReportingRequestType ProtocolIE-ID ::= 33 + id-MaskedIMEISV ProtocolIE-ID ::= 34 + id-MessageIdentifier ProtocolIE-ID ::= 35 + id-MobilityRestrictionList ProtocolIE-ID ::= 36 + id-NASC ProtocolIE-ID ::= 37 + id-NAS-PDU ProtocolIE-ID ::= 38 + id-NASSecurityParametersFromNGRAN ProtocolIE-ID ::= 39 + id-NewAMF-UE-NGAP-ID ProtocolIE-ID ::= 40 + id-NewSecurityContextInd ProtocolIE-ID ::= 41 + id-NGAP-Message ProtocolIE-ID ::= 42 + id-NGRAN-CGI ProtocolIE-ID ::= 43 + id-NGRANTraceID ProtocolIE-ID ::= 44 + id-NR-CGI ProtocolIE-ID ::= 45 + id-NRPPa-PDU ProtocolIE-ID ::= 46 + id-NumberOfBroadcastsRequested ProtocolIE-ID ::= 47 + id-OldAMF ProtocolIE-ID ::= 48 + id-OverloadStartNSSAIList ProtocolIE-ID ::= 49 + id-PagingDRX ProtocolIE-ID ::= 50 + id-PagingOrigin ProtocolIE-ID ::= 51 + id-PagingPriority ProtocolIE-ID ::= 52 + id-PDUSessionResourceAdmittedList ProtocolIE-ID ::= 53 + id-PDUSessionResourceFailedToModifyListModRes ProtocolIE-ID ::= 54 + id-PDUSessionResourceFailedToSetupListCxtRes ProtocolIE-ID ::= 55 + id-PDUSessionResourceFailedToSetupListHOAck ProtocolIE-ID ::= 56 + id-PDUSessionResourceFailedToSetupListPSReq ProtocolIE-ID ::= 57 + id-PDUSessionResourceFailedToSetupListSURes ProtocolIE-ID ::= 58 + id-PDUSessionResourceHandoverList ProtocolIE-ID ::= 59 + id-PDUSessionResourceListCxtRelCpl ProtocolIE-ID ::= 60 + id-PDUSessionResourceListHORqd ProtocolIE-ID ::= 61 + id-PDUSessionResourceModifyListModCfm ProtocolIE-ID ::= 62 + id-PDUSessionResourceModifyListModInd ProtocolIE-ID ::= 63 + id-PDUSessionResourceModifyListModReq ProtocolIE-ID ::= 64 + id-PDUSessionResourceModifyListModRes ProtocolIE-ID ::= 65 + id-PDUSessionResourceNotifyList ProtocolIE-ID ::= 66 + id-PDUSessionResourceReleasedListNot ProtocolIE-ID ::= 67 + id-PDUSessionResourceReleasedListPSAck ProtocolIE-ID ::= 68 + id-PDUSessionResourceReleasedListPSFail ProtocolIE-ID ::= 69 + id-PDUSessionResourceReleasedListRelRes ProtocolIE-ID ::= 70 + id-PDUSessionResourceSetupListCxtReq ProtocolIE-ID ::= 71 + id-PDUSessionResourceSetupListCxtRes ProtocolIE-ID ::= 72 + id-PDUSessionResourceSetupListHOReq ProtocolIE-ID ::= 73 + id-PDUSessionResourceSetupListSUReq ProtocolIE-ID ::= 74 + id-PDUSessionResourceSetupListSURes ProtocolIE-ID ::= 75 + id-PDUSessionResourceToBeSwitchedDLList ProtocolIE-ID ::= 76 + id-PDUSessionResourceSwitchedList ProtocolIE-ID ::= 77 + id-PDUSessionResourceToReleaseListHOCmd ProtocolIE-ID ::= 78 + id-PDUSessionResourceToReleaseListRelCmd ProtocolIE-ID ::= 79 + id-PLMNSupportList ProtocolIE-ID ::= 80 + id-PWSFailedCellIDList ProtocolIE-ID ::= 81 + id-RANNodeName ProtocolIE-ID ::= 82 + id-RANPagingPriority ProtocolIE-ID ::= 83 + id-RANStatusTransfer-TransparentContainer ProtocolIE-ID ::= 84 + id-RAN-UE-NGAP-ID ProtocolIE-ID ::= 85 + id-RelativeAMFCapacity ProtocolIE-ID ::= 86 + id-RepetitionPeriod ProtocolIE-ID ::= 87 + id-ResetType ProtocolIE-ID ::= 88 + id-RoutingID ProtocolIE-ID ::= 89 + id-RRCEstablishmentCause ProtocolIE-ID ::= 90 + id-RRCInactiveTransitionReportRequest ProtocolIE-ID ::= 91 + id-RRCState ProtocolIE-ID ::= 92 + id-SecurityContext ProtocolIE-ID ::= 93 + id-SecurityKey ProtocolIE-ID ::= 94 + id-SerialNumber ProtocolIE-ID ::= 95 + id-ServedGUAMIList ProtocolIE-ID ::= 96 + id-SliceSupportList ProtocolIE-ID ::= 97 + id-SONConfigurationTransferDL ProtocolIE-ID ::= 98 + id-SONConfigurationTransferUL ProtocolIE-ID ::= 99 + id-SourceAMF-UE-NGAP-ID ProtocolIE-ID ::= 100 + id-SourceToTarget-TransparentContainer ProtocolIE-ID ::= 101 + id-SupportedTAList ProtocolIE-ID ::= 102 + id-TAIListForPaging ProtocolIE-ID ::= 103 + id-TAIListForRestart ProtocolIE-ID ::= 104 + id-TargetID ProtocolIE-ID ::= 105 + id-TargetToSource-TransparentContainer ProtocolIE-ID ::= 106 + id-TimeToWait ProtocolIE-ID ::= 107 + id-TraceActivation ProtocolIE-ID ::= 108 + id-TraceCollectionEntityIPAddress ProtocolIE-ID ::= 109 + id-UEAggregateMaximumBitRate ProtocolIE-ID ::= 110 + id-UE-associatedLogicalNG-connectionList ProtocolIE-ID ::= 111 + id-UEContextRequest ProtocolIE-ID ::= 112 + id-UE-NGAP-IDs ProtocolIE-ID ::= 114 + id-UEPagingIdentity ProtocolIE-ID ::= 115 + id-UEPresenceInAreaOfInterestList ProtocolIE-ID ::= 116 + id-UERadioCapability ProtocolIE-ID ::= 117 + id-UERadioCapabilityForPaging ProtocolIE-ID ::= 118 + id-UESecurityCapabilities ProtocolIE-ID ::= 119 + id-UnavailableGUAMIList ProtocolIE-ID ::= 120 + id-UserLocationInformation ProtocolIE-ID ::= 121 + id-WarningAreaList ProtocolIE-ID ::= 122 + id-WarningMessageContents ProtocolIE-ID ::= 123 + id-WarningSecurityInfo ProtocolIE-ID ::= 124 + id-WarningType ProtocolIE-ID ::= 125 + id-AdditionalUL-NGU-UP-TNLInformation ProtocolIE-ID ::= 126 + id-DataForwardingNotPossible ProtocolIE-ID ::= 127 + id-DL-NGU-UP-TNLInformation ProtocolIE-ID ::= 128 + id-NetworkInstance ProtocolIE-ID ::= 129 + id-PDUSessionAggregateMaximumBitRate ProtocolIE-ID ::= 130 + id-PDUSessionResourceFailedToModifyListModCfm ProtocolIE-ID ::= 131 + id-PDUSessionResourceFailedToSetupListCxtFail ProtocolIE-ID ::= 132 + id-PDUSessionResourceListCxtRelReq ProtocolIE-ID ::= 133 + id-PDUSessionType ProtocolIE-ID ::= 134 + id-QosFlowAddOrModifyRequestList ProtocolIE-ID ::= 135 + id-QosFlowSetupRequestList ProtocolIE-ID ::= 136 + id-QosFlowToReleaseList ProtocolIE-ID ::= 137 + id-SecurityIndication ProtocolIE-ID ::= 138 + id-UL-NGU-UP-TNLInformation ProtocolIE-ID ::= 139 + id-UL-NGU-UP-TNLModifyList ProtocolIE-ID ::= 140 + id-WarningAreaCoordinates ProtocolIE-ID ::= 141 + id-PDUSessionResourceSecondaryRATUsageList ProtocolIE-ID ::= 142 + id-HandoverFlag ProtocolIE-ID ::= 143 + id-SecondaryRATUsageInformation ProtocolIE-ID ::= 144 + id-PDUSessionResourceReleaseResponseTransfer ProtocolIE-ID ::= 145 + id-RedirectionVoiceFallback ProtocolIE-ID ::= 146 + id-UERetentionInformation ProtocolIE-ID ::= 147 + id-S-NSSAI ProtocolIE-ID ::= 148 + id-PSCellInformation ProtocolIE-ID ::= 149 + id-LastEUTRAN-PLMNIdentity ProtocolIE-ID ::= 150 + id-MaximumIntegrityProtectedDataRate-DL ProtocolIE-ID ::= 151 + id-AdditionalDLForwardingUPTNLInformation ProtocolIE-ID ::= 152 + id-AdditionalDLUPTNLInformationForHOList ProtocolIE-ID ::= 153 + id-AdditionalNGU-UP-TNLInformation ProtocolIE-ID ::= 154 + id-AdditionalDLQosFlowPerTNLInformation ProtocolIE-ID ::= 155 + id-SecurityResult ProtocolIE-ID ::= 156 + id-ENDC-SONConfigurationTransferDL ProtocolIE-ID ::= 157 + id-ENDC-SONConfigurationTransferUL ProtocolIE-ID ::= 158 + id-OldAssociatedQosFlowList-ULendmarkerexpected ProtocolIE-ID ::= 159 + id-CNTypeRestrictionsForEquivalent ProtocolIE-ID ::= 160 + id-CNTypeRestrictionsForServing ProtocolIE-ID ::= 161 + id-NewGUAMI ProtocolIE-ID ::= 162 + id-ULForwarding ProtocolIE-ID ::= 163 + id-ULForwardingUP-TNLInformation ProtocolIE-ID ::= 164 + id-CNAssistedRANTuning ProtocolIE-ID ::= 165 + id-CommonNetworkInstance ProtocolIE-ID ::= 166 + id-NGRAN-TNLAssociationToRemoveList ProtocolIE-ID ::= 167 + id-TNLAssociationTransportLayerAddressNGRAN ProtocolIE-ID ::= 168 + id-EndpointIPAddressAndPort ProtocolIE-ID ::= 169 + id-LocationReportingAdditionalInfo ProtocolIE-ID ::= 170 + id-SourceToTarget-AMFInformationReroute ProtocolIE-ID ::= 171 + id-AdditionalULForwardingUPTNLInformation ProtocolIE-ID ::= 172 + id-SCTP-TLAs ProtocolIE-ID ::= 173 + id-SelectedPLMNIdentity ProtocolIE-ID ::= 174 + + +END +-- ASN1STOP + +-- ASN1START +-- ************************************************************** +-- +-- Container definitions +-- +-- ************************************************************** + +NGAP-Containers { +itu-t (0) identified-organization (4) etsi (0) mobileDomain (0) +ngran-Access (22) modules (3) ngap (1) version1 (1) ngap-Containers (5) } + +DEFINITIONS AUTOMATIC TAGS ::= + +BEGIN + +-- ************************************************************** +-- +-- IE parameter types from other modules. +-- +-- ************************************************************** + +IMPORTS + + Criticality, + Presence, + PrivateIE-ID, + ProtocolExtensionID, + ProtocolIE-ID +FROM NGAP-CommonDataTypes + + maxPrivateIEs, + maxProtocolExtensions, + maxProtocolIEs +FROM NGAP-Constants; + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +NGAP-PROTOCOL-IES ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol IEs +-- +-- ************************************************************** + +NGAP-PROTOCOL-IES-PAIR ::= CLASS { + &id ProtocolIE-ID UNIQUE, + &firstCriticality Criticality, + &FirstValue, + &secondCriticality Criticality, + &SecondValue, + &presence Presence +} +WITH SYNTAX { + ID &id + FIRST CRITICALITY &firstCriticality + FIRST TYPE &FirstValue + SECOND CRITICALITY &secondCriticality + SECOND TYPE &SecondValue + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Protocol Extensions +-- +-- ************************************************************** + +NGAP-PROTOCOL-EXTENSION ::= CLASS { + &id ProtocolExtensionID UNIQUE, + &criticality Criticality, + &Extension, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + EXTENSION &Extension + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Class Definition for Private IEs +-- +-- ************************************************************** + +NGAP-PRIVATE-IES ::= CLASS { + &id PrivateIE-ID, + &criticality Criticality, + &Value, + &presence Presence +} +WITH SYNTAX { + ID &id + CRITICALITY &criticality + TYPE &Value + PRESENCE &presence +} + +-- ************************************************************** +-- +-- Container for Protocol IEs +-- +-- ************************************************************** + +ProtocolIE-Container {NGAP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-SingleContainer {NGAP-PROTOCOL-IES : IEsSetParam} ::= + ProtocolIE-Field {{IEsSetParam}} + +ProtocolIE-Field {NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE { + id NGAP-PROTOCOL-IES.&id ({IEsSetParam}), + criticality NGAP-PROTOCOL-IES.&criticality ({IEsSetParam}{@id}), + value NGAP-PROTOCOL-IES.&Value ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Protocol IE Pairs +-- +-- ************************************************************** + +ProtocolIE-ContainerPair {NGAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (0..maxProtocolIEs)) OF + ProtocolIE-FieldPair {{IEsSetParam}} + +ProtocolIE-FieldPair {NGAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE { + id NGAP-PROTOCOL-IES-PAIR.&id ({IEsSetParam}), + firstCriticality NGAP-PROTOCOL-IES-PAIR.&firstCriticality ({IEsSetParam}{@id}), + firstValue NGAP-PROTOCOL-IES-PAIR.&FirstValue ({IEsSetParam}{@id}), + secondCriticality NGAP-PROTOCOL-IES-PAIR.&secondCriticality ({IEsSetParam}{@id}), + secondValue NGAP-PROTOCOL-IES-PAIR.&SecondValue ({IEsSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container Lists for Protocol IE Containers +-- +-- ************************************************************** + +ProtocolIE-ContainerList {INTEGER : lowerBound, INTEGER : upperBound, NGAP-PROTOCOL-IES : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-SingleContainer {{IEsSetParam}} + +ProtocolIE-ContainerPairList {INTEGER : lowerBound, INTEGER : upperBound, NGAP-PROTOCOL-IES-PAIR : IEsSetParam} ::= + SEQUENCE (SIZE (lowerBound..upperBound)) OF + ProtocolIE-ContainerPair {{IEsSetParam}} + +-- ************************************************************** +-- +-- Container for Protocol Extensions +-- +-- ************************************************************** + +ProtocolExtensionContainer {NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= + SEQUENCE (SIZE (1..maxProtocolExtensions)) OF + ProtocolExtensionField {{ExtensionSetParam}} + +ProtocolExtensionField {NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE { + id NGAP-PROTOCOL-EXTENSION.&id ({ExtensionSetParam}), + criticality NGAP-PROTOCOL-EXTENSION.&criticality ({ExtensionSetParam}{@id}), + extensionValue NGAP-PROTOCOL-EXTENSION.&Extension ({ExtensionSetParam}{@id}) +} + +-- ************************************************************** +-- +-- Container for Private IEs +-- +-- ************************************************************** + +PrivateIE-Container {NGAP-PRIVATE-IES : IEsSetParam } ::= + SEQUENCE (SIZE (1..maxPrivateIEs)) OF + PrivateIE-Field {{IEsSetParam}} + +PrivateIE-Field {NGAP-PRIVATE-IES : IEsSetParam} ::= SEQUENCE { + id NGAP-PRIVATE-IES.&id ({IEsSetParam}), + criticality NGAP-PRIVATE-IES.&criticality ({IEsSetParam}{@id}), + value NGAP-PRIVATE-IES.&Value ({IEsSetParam}{@id}) +} + +END +-- ASN1STOP \ No newline at end of file diff --git a/common/utils/itti_analyzer/libparser/field_type.h b/openair3/NGAP/ngap_common.c similarity index 70% rename from common/utils/itti_analyzer/libparser/field_type.h rename to openair3/NGAP/ngap_common.c index 329e90c3be..53b04e09eb 100644 --- a/common/utils/itti_analyzer/libparser/field_type.h +++ b/openair3/NGAP/ngap_common.c @@ -19,17 +19,23 @@ * contact@openairinterface.org */ -#include "types.h" +/*! \file ngap_common.c + * \brief ngap procedures for both gNB and AMF + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ -#ifndef FIELD_TYPE_H_ -#define FIELD_TYPE_H_ +#include -int field_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); +#include "ngap_common.h" +#include "NGAP_NGAP-PDU.h" -int field_type_file_print(types_t *type, int indent, FILE *file); -int field_type_hr_display(types_t *type, int indent); +int asn1_xer_print = 0; -#endif /* FIELD_TYPE_H_ */ + +void ngap_handle_criticality(NGAP_Criticality_t criticality) +{ +} diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h new file mode 100644 index 0000000000..f0302a88c7 --- /dev/null +++ b/openair3/NGAP/ngap_common.h @@ -0,0 +1,163 @@ +/* + * 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 ngap_common.h + * \brief ngap procedures for both gNB and AMF + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +/** @defgroup _ngap_impl_ NGAP Layer Reference Implementation + * @ingroup _ref_implementation_ + * @{ + */ + + +#if HAVE_CONFIG_H_ +# include "config.h" +#endif + +#ifndef NGAP_COMMON_H_ +#define NGAP_COMMON_H_ + + +#include "common/utils/LOG/log.h" +/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system + Would be cleaner to modify asn_internal.h but it seems to come + from non oai source, with BSD license, so prefer to do that here.. +*/ +#ifdef ASN_DEBUG +# undef ASN_DEBUG +#endif +#define ASN_DEBUG( x... ) LOG_I(ASN, x) + +#include "NGAP_ProtocolIE-Field.h" +#include "NGAP_NGAP-PDU.h" +#include "NGAP_InitiatingMessage.h" +#include "NGAP_SuccessfulOutcome.h" +#include "NGAP_UnsuccessfulOutcome.h" +#include "NGAP_ProtocolIE-Field.h" +#include "NGAP_ProtocolIE-FieldPair.h" +#include "NGAP_ProtocolIE-ContainerPair.h" +#include "NGAP_ProtocolExtensionField.h" +#include "NGAP_ProtocolExtensionContainer.h" +#include "NGAP_asn_constant.h" +#include "NGAP_SupportedTAItem.h" +#include "NGAP_ServedGUAMIItem.h" +#include "NGAP_BroadcastPLMNItem.h" +#include "NGAP_SliceSupportItem.h" +#include "NGAP_PLMNSupportItem.h" +#include "NGAP_PDUSessionResourceSetupResponseTransfer.h" +#include "NGAP_PDUSessionResourceSetupUnsuccessfulTransfer.h" +#include "NGAP_PDUSessionResourceSetupItemCxtRes.h" +#include "NGAP_PDUSessionResourceFailedToSetupItemCxtRes.h" +#include "NGAP_PDUSessionResourceSetupItemSUReq.h" +#include "NGAP_PDUSessionResourceSetupItemSURes.h" +#include "NGAP_PDUSessionResourceFailedToSetupItemSURes.h" +#include "NGAP_AssociatedQosFlowItem.h" +#include "NGAP_PDUSessionResourceSetupRequestTransfer.h" +#include "NGAP_PDUSessionResourceSetupItemCxtReq.h" +#include "NGAP_QosFlowSetupRequestItem.h" +#include "NGAP_AllowedNSSAI-Item.h" +#include "NGAP_PDUSessionResourceModifyItemModRes.h" +#include "NGAP_PDUSessionResourceFailedToModifyItemModRes.h" +#include "NGAP_PDUSessionResourceModifyUnsuccessfulTransfer.h" +#include "NGAP_PDUSessionResourceReleasedItemRelRes.h" +#include "NGAP_PDUSessionResourceToReleaseItemRelCmd.h" +#include "NGAP_PDUSessionResourceModifyItemModReq.h" +#include "NGAP_PDUSessionResourceModifyRequestTransfer.h" +#include "NGAP_QosFlowAddOrModifyRequestItem.h" +#include "NGAP_TAIListForPagingItem.h" +#include "NGAP_GNB-ID.h" +#include "NGAP_GlobalGNB-ID.h" +#include "NGAP_GTPTunnel.h" +#include "NGAP_UE-NGAP-ID-pair.h" +#include "NGAP_UserLocationInformationNR.h" + +/* Checking version of ASN1C compiler */ +#if (ASN1C_ENVIRONMENT_VERSION < ASN1C_MINIMUM_VERSION) +# error "You are compiling ngap with the wrong version of ASN1C" +#endif + +#ifndef FALSE +# define FALSE (0) +#endif +#ifndef TRUE +# define TRUE (!FALSE) +#endif + +#define NGAP_UE_ID_FMT "0x%06"PRIX32 + +extern int asn_debug; +extern int asn1_xer_print; + +#if defined(ENB_MODE) +# include "common/utils/LOG/log.h" +# include "ngap_gNB_default_values.h" +# define NGAP_ERROR(x, args...) LOG_E(NGAP, x, ##args) +# define NGAP_WARN(x, args...) LOG_W(NGAP, x, ##args) +# define NGAP_TRAF(x, args...) LOG_I(NGAP, x, ##args) +# define NGAP_INFO(x, args...) LOG_I(NGAP, x, ##args) +# define NGAP_DEBUG(x, args...) LOG_I(NGAP, x, ##args) +#else +# include "amf_default_values.h" +# define NGAP_ERROR(x, args...) do { fprintf(stdout, "[NGAP][E]"x, ##args); } while(0) +# define NGAP_WARN(x, args...) do { fprintf(stdout, "[NGAP][W]"x, ##args); } while(0) +# define NGAP_TRAF(x, args...) do { fprintf(stdout, "[NGAP][T]"x, ##args); } while(0) +# define NGAP_INFO(x, args...) do { fprintf(stdout, "[NGAP][I]"x, ##args); } while(0) +# define NGAP_DEBUG(x, args...) do { fprintf(stdout, "[NGAP][D]"x, ##args); } while(0) +#endif + + +#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do {\ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; \ + ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (ie == NULL ) { \ + NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ + } \ + if (mandatory) DevAssert(ie != NULL); \ + } while(0) +/** \brief Function callback prototype. + **/ +typedef int (*ngap_message_decoded_callback)( + uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu +); + +/** \brief Handle criticality + \param criticality Criticality of the IE + @returns void + **/ +void ngap_handle_criticality(NGAP_Criticality_t criticality); + +#endif /* NGAP_COMMON_H_ */ diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c new file mode 100644 index 0000000000..a5dfc88b35 --- /dev/null +++ b/openair3/NGAP/ngap_gNB.c @@ -0,0 +1,540 @@ +/* + * 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 ngap_gNB.c + * \brief NGAP gNB task + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + + +#include +#include +#include +#include +#include + +#include "tree.h" +#include "queue.h" + +#include "intertask_interface.h" + +#include "ngap_gNB_default_values.h" + +#include "ngap_common.h" + +#include "ngap_gNB_defs.h" +#include "ngap_gNB.h" +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_handlers.h" +#include "ngap_gNB_nnsf.h" + +#include "ngap_gNB_nas_procedures.h" +#include "ngap_gNB_management_procedures.h" +#include "ngap_gNB_context_management_procedures.h" + +#include "ngap_gNB_itti_messaging.h" + +#include "ngap_gNB_ue_context.h" // test, to be removed +#include "msc.h" + +#include "assertions.h" +#include "conversions.h" +#if defined(TEST_S1C_AMF) + #include "oaisim_amf_test_s1c.h" +#endif + +ngap_gNB_config_t ngap_config; + +static int ngap_gNB_generate_ng_setup_request( + ngap_gNB_instance_t *instance_p, ngap_gNB_amf_data_t *ngap_amf_data_p); + +void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *ngap_register_gNB); + +void ngap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); + +uint32_t ngap_generate_gNB_id(void) { + char *out; + char hostname[50]; + int ret; + uint32_t gNB_id; + /* Retrieve the host name */ + ret = gethostname(hostname, sizeof(hostname)); + DevAssert(ret == 0); + out = crypt(hostname, "eurecom"); + DevAssert(out != NULL); + gNB_id = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | out[3]); + return gNB_id; +} + +static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p, + net_ip_address_t *amf_ip_address, + net_ip_address_t *local_ip_addr, + uint16_t in_streams, + uint16_t out_streams, + uint8_t broadcast_plmn_num, + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) { + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + ngap_gNB_amf_data_t *ngap_amf_data_p = NULL; + + DevAssert(instance_p != NULL); + DevAssert(amf_ip_address != NULL); + message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + sctp_new_association_req_p->port = NGAP_PORT_NUMBER; + sctp_new_association_req_p->ppid = NGAP_SCTP_PPID; + sctp_new_association_req_p->in_streams = in_streams; + sctp_new_association_req_p->out_streams = out_streams; + memcpy(&sctp_new_association_req_p->remote_address, + amf_ip_address, + sizeof(*amf_ip_address)); + memcpy(&sctp_new_association_req_p->local_address, + local_ip_addr, + sizeof(*local_ip_addr)); + NGAP_INFO("[gNB %ld] check the amf registration state\n",instance_p->instance); + + /* Create new AMF descriptor */ + ngap_amf_data_p = calloc(1, sizeof(*ngap_amf_data_p)); + DevAssert(ngap_amf_data_p != NULL); + ngap_amf_data_p->cnx_id = ngap_gNB_fetch_add_global_cnx_id(); + sctp_new_association_req_p->ulp_cnx_id = ngap_amf_data_p->cnx_id; + ngap_amf_data_p->assoc_id = -1; + ngap_amf_data_p->broadcast_plmn_num = broadcast_plmn_num; + memcpy(&ngap_amf_data_p->amf_s1_ip, + amf_ip_address, + sizeof(*amf_ip_address)); + for (int i = 0; i < broadcast_plmn_num; ++i) + ngap_amf_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; + + ngap_amf_data_p->ngap_gNB_instance = instance_p; + STAILQ_INIT(&ngap_amf_data_p->served_guami); + /* Insert the new descriptor in list of known AMF + * but not yet associated. + */ + RB_INSERT(ngap_amf_map, &instance_p->ngap_amf_head, ngap_amf_data_p); + ngap_amf_data_p->state = NGAP_GNB_STATE_DISCONNECTED; + instance_p->ngap_amf_nb ++; + instance_p->ngap_amf_pending_nb ++; + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); +} + +void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t *ngap_register_gNB) { + ngap_gNB_instance_t *new_instance; + uint8_t index; + DevAssert(ngap_register_gNB != NULL); + /* Look if the provided instance already exists */ + new_instance = ngap_gNB_get_instance(instance); + + if (new_instance != NULL) { + /* Checks if it is a retry on the same gNB */ + DevCheck(new_instance->gNB_id == ngap_register_gNB->gNB_id, new_instance->gNB_id, ngap_register_gNB->gNB_id, 0); + DevCheck(new_instance->cell_type == ngap_register_gNB->cell_type, new_instance->cell_type, ngap_register_gNB->cell_type, 0); + DevCheck(new_instance->num_plmn == ngap_register_gNB->num_plmn, new_instance->num_plmn, ngap_register_gNB->num_plmn, 0); + DevCheck(new_instance->tac == ngap_register_gNB->tac, new_instance->tac, ngap_register_gNB->tac, 0); + + for (int i = 0; i < new_instance->num_plmn; i++) { + DevCheck(new_instance->mcc[i] == ngap_register_gNB->mcc[i], new_instance->mcc[i], ngap_register_gNB->mcc[i], 0); + DevCheck(new_instance->mnc[i] == ngap_register_gNB->mnc[i], new_instance->mnc[i], ngap_register_gNB->mnc[i], 0); + DevCheck(new_instance->mnc_digit_length[i] == ngap_register_gNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], ngap_register_gNB->mnc_digit_length[i], 0); + } + + DevCheck(new_instance->default_drx == ngap_register_gNB->default_drx, new_instance->default_drx, ngap_register_gNB->default_drx, 0); + } else { + new_instance = calloc(1, sizeof(ngap_gNB_instance_t)); + DevAssert(new_instance != NULL); + RB_INIT(&new_instance->ngap_ue_head); + RB_INIT(&new_instance->ngap_amf_head); + /* Copy usefull parameters */ + new_instance->instance = instance; + new_instance->gNB_name = ngap_register_gNB->gNB_name; + new_instance->gNB_id = ngap_register_gNB->gNB_id; + new_instance->cell_type = ngap_register_gNB->cell_type; + new_instance->tac = ngap_register_gNB->tac; + + memcpy(&new_instance->gNB_ng_ip, + &ngap_register_gNB->gnb_ip_address, + sizeof(ngap_register_gNB->gnb_ip_address)); + + for (int i = 0; i < ngap_register_gNB->num_plmn; i++) { + new_instance->mcc[i] = ngap_register_gNB->mcc[i]; + new_instance->mnc[i] = ngap_register_gNB->mnc[i]; + new_instance->mnc_digit_length[i] = ngap_register_gNB->mnc_digit_length[i]; + + new_instance->num_nssai[i] = ngap_register_gNB->num_nssai[i]; + } + + new_instance->num_plmn = ngap_register_gNB->num_plmn; + new_instance->default_drx = ngap_register_gNB->default_drx; + + memcpy(new_instance->s_nssai, ngap_register_gNB->s_nssai, sizeof(ngap_register_gNB->s_nssai)); + + /* Add the new instance to the list of gNB (meaningfull in virtual mode) */ + ngap_gNB_insert_new_instance(new_instance); + NGAP_INFO("Registered new gNB[%ld] and %s gNB id %u\n", + instance, + ngap_register_gNB->cell_type == CELL_MACRO_GNB ? "macro" : "home", + ngap_register_gNB->gNB_id); + } + + DevCheck(ngap_register_gNB->nb_amf <= NGAP_MAX_NB_AMF_IP_ADDRESS, + NGAP_MAX_NB_AMF_IP_ADDRESS, ngap_register_gNB->nb_amf, 0); + + /* Trying to connect to provided list of AMF ip address */ + for (index = 0; index < ngap_register_gNB->nb_amf; index++) { + net_ip_address_t *amf_ip = &ngap_register_gNB->amf_ip_address[index]; + struct ngap_gNB_amf_data_s *amf = NULL; + RB_FOREACH(amf, ngap_amf_map, &new_instance->ngap_amf_head) { + /* Compare whether IPv4 and IPv6 information is already present, in which + * wase we do not register again */ + if (amf->amf_s1_ip.ipv4 == amf_ip->ipv4 && (!amf_ip->ipv4 + || strncmp(amf->amf_s1_ip.ipv4_address, amf_ip->ipv4_address, 16) == 0) + && amf->amf_s1_ip.ipv6 == amf_ip->ipv6 && (!amf_ip->ipv6 + || strncmp(amf->amf_s1_ip.ipv6_address, amf_ip->ipv6_address, 46) == 0)) + break; + } + if (amf) + continue; + ngap_gNB_register_amf(new_instance, + amf_ip, + &ngap_register_gNB->gnb_ip_address, + ngap_register_gNB->sctp_in_streams, + ngap_register_gNB->sctp_out_streams, + ngap_register_gNB->broadcast_plmn_num[index], + ngap_register_gNB->broadcast_plmn_index[index]); + } +} + +void ngap_gNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + ngap_gNB_instance_t *instance_p; + ngap_gNB_amf_data_t *ngap_amf_data_p; + DevAssert(sctp_new_association_resp != NULL); + instance_p = ngap_gNB_get_instance(instance); + DevAssert(instance_p != NULL); + ngap_amf_data_p = ngap_gNB_get_AMF(instance_p, -1, + sctp_new_association_resp->ulp_cnx_id); + DevAssert(ngap_amf_data_p != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + NGAP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + ngap_handle_ng_setup_message(ngap_amf_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); + return; + } + + /* Update parameters */ + ngap_amf_data_p->assoc_id = sctp_new_association_resp->assoc_id; + ngap_amf_data_p->in_streams = sctp_new_association_resp->in_streams; + ngap_amf_data_p->out_streams = sctp_new_association_resp->out_streams; + /* Prepare new NG Setup Request */ + ngap_gNB_generate_ng_setup_request(instance_p, ngap_amf_data_p); +} + +static +void ngap_gNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { + int result; + DevAssert(sctp_data_ind != NULL); +#if defined(TEST_S1C_AMF) + amf_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); +#else + ngap_gNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, + sctp_data_ind->buffer, sctp_data_ind->buffer_length); +#endif + result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); +} + +void ngap_gNB_init(void) { + NGAP_DEBUG("Starting NGAP layer\n"); + ngap_gNB_prepare_internal_data(); + itti_mark_task_ready(TASK_NGAP); + MSC_START_USE(); +} + +void *ngap_gNB_process_itti_msg(void *notUsed) { + MessageDef *received_msg = NULL; + int result; + itti_receive_msg(TASK_NGAP, &received_msg); + + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + NGAP_WARN(" *** Exiting NGAP thread\n"); + itti_exit_task(); + break; + + case NGAP_REGISTER_GNB_REQ: { + /* Register a new gNB. + * in Virtual mode gNBs will be distinguished using the mod_id/ + * Each gNB has to send an NGAP_REGISTER_GNB message with its + * own parameters. + */ + ngap_gNB_handle_register_gNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_REGISTER_GNB_REQ(received_msg)); + } + break; + + case SCTP_NEW_ASSOCIATION_RESP: { + ngap_gNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &received_msg->ittiMsg.sctp_new_association_resp); + } + break; + + case SCTP_DATA_IND: { + ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); + } + break; + + case NGAP_NAS_FIRST_REQ: { + ngap_gNB_handle_nas_first_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_NAS_FIRST_REQ(received_msg)); + } + break; + + case NGAP_UPLINK_NAS: { + ngap_gNB_nas_uplink(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_UPLINK_NAS(received_msg)); + } + break; + + case NGAP_UE_CAPABILITIES_IND: { + ngap_gNB_ue_capabilities(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_UE_CAPABILITIES_IND(received_msg)); + } + break; + + case NGAP_INITIAL_CONTEXT_SETUP_RESP: { + ngap_gNB_initial_ctxt_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_INITIAL_CONTEXT_SETUP_RESP(received_msg)); + } + break; + + case NGAP_PDUSESSION_SETUP_RESP: { + ngap_gNB_pdusession_setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_PDUSESSION_SETUP_RESP(received_msg)); + } + break; + + case NGAP_PDUSESSION_MODIFY_RESP: { + ngap_gNB_pdusession_modify_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_PDUSESSION_MODIFY_RESP(received_msg)); + } + break; + + case NGAP_NAS_NON_DELIVERY_IND: { + ngap_gNB_nas_non_delivery_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_NAS_NON_DELIVERY_IND(received_msg)); + } + break; + + case NGAP_PATH_SWITCH_REQ: { + ngap_gNB_path_switch_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_PATH_SWITCH_REQ(received_msg)); + } + break; + + case NGAP_PDUSESSION_MODIFICATION_IND: { + ngap_gNB_generate_PDUSESSION_Modification_Indication(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_PDUSESSION_MODIFICATION_IND(received_msg)); + } + break; + + case NGAP_UE_CONTEXT_RELEASE_COMPLETE: { + ngap_ue_context_release_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); + } + break; + + case NGAP_UE_CONTEXT_RELEASE_REQ: { + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; // test + struct ngap_gNB_ue_context_s *ue_context_p = NULL; // test + ngap_ue_context_release_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_UE_CONTEXT_RELEASE_REQ(received_msg)); + ngap_gNB_instance_p = ngap_gNB_get_instance(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // test + DevAssert(ngap_gNB_instance_p != NULL); // test + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id)) == NULL) { // test + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_ERROR("Failed to find ue context associated with gNB ue ngap id: %u\n", + NGAP_UE_CONTEXT_RELEASE_REQ(received_msg).gNB_ue_ngap_id); // test + } // test + } + break; + + case NGAP_PDUSESSION_RELEASE_RESPONSE: { + ngap_gNB_pdusession_release_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &NGAP_PDUSESSION_RELEASE_RESPONSE(received_msg)); + } + break; + + default: + NGAP_ERROR("Received unhandled message: %d:%s\n", + ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; + return NULL; +} + + +void *ngap_gNB_task(void *arg) { + ngap_gNB_init(); + + while (1) { + (void) ngap_gNB_process_itti_msg(NULL); + } + + return NULL; +} + +//----------------------------------------------------------------------------- +/* +* gNB generate a NG setup request towards AMF +*/ +static int ngap_gNB_generate_ng_setup_request( + ngap_gNB_instance_t *instance_p, + ngap_gNB_amf_data_t *ngap_amf_data_p) +//----------------------------------------------------------------------------- +{ + NGAP_NGAP_PDU_t pdu; + NGAP_NGSetupRequest_t *out = NULL; + NGAP_NGSetupRequestIEs_t *ie = NULL; + NGAP_SupportedTAItem_t *ta = NULL; + NGAP_BroadcastPLMNItem_t *plmn = NULL; + NGAP_SliceSupportItem_t *ssi = NULL; + uint8_t *buffer = NULL; + uint32_t len = 0; + int ret = 0; + DevAssert(instance_p != NULL); + DevAssert(ngap_amf_data_p != NULL); + ngap_amf_data_p->state = NGAP_GNB_STATE_WAITING; + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = CALLOC(1, sizeof(struct NGAP_InitiatingMessage)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NGSetup; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_reject; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NGSetupRequest; + out = &pdu.choice.initiatingMessage->value.choice.NGSetupRequest; + /* mandatory */ + ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_GlobalRANNodeID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NGSetupRequestIEs__value_PR_GlobalRANNodeID; + ie->value.choice.GlobalRANNodeID.present = NGAP_GlobalRANNodeID_PR_globalGNB_ID; + ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID = CALLOC(1, sizeof(struct NGAP_GlobalGNB_ID)); + MCC_MNC_TO_PLMNID(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[0]], + instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[0]], + instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[0]], + &(ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->pLMNIdentity)); + ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.present = NGAP_GNB_ID_PR_gNB_ID; + MACRO_GNB_ID_TO_BIT_STRING(instance_p->gNB_id, + &ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID); + NGAP_INFO("%u -> %02x%02x%02x%02x\n", instance_p->gNB_id, + ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[0], + ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[1], + ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[2], + ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.choice.gNB_ID.buf[3]); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (instance_p->gNB_name) { + ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RANNodeName; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_NGSetupRequestIEs__value_PR_RANNodeName; + OCTET_STRING_fromBuf(&ie->value.choice.RANNodeName, instance_p->gNB_name, + strlen(instance_p->gNB_name)); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_SupportedTAList; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NGSetupRequestIEs__value_PR_SupportedTAList; + { + ta = (NGAP_SupportedTAItem_t *)calloc(1, sizeof(NGAP_SupportedTAItem_t)); + INT24_TO_OCTET_STRING(instance_p->tac, &ta->tAC); + { + for (int i = 0; i < ngap_amf_data_p->broadcast_plmn_num; ++i) { + plmn = (NGAP_BroadcastPLMNItem_t *)calloc(1, sizeof(NGAP_BroadcastPLMNItem_t)); + MCC_MNC_TO_TBCD(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[i]], + instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[i]], + instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[i]], + &plmn->pLMNIdentity); + + for(int si = 0; si < instance_p->num_nssai[i]; si++) { + ssi = (NGAP_SliceSupportItem_t *)calloc(1, sizeof(NGAP_SliceSupportItem_t)); + INT8_TO_OCTET_STRING(instance_p->s_nssai[i][si].sST, &ssi->s_NSSAI.sST); + + if(instance_p->s_nssai[i]->sD_flag) { + ssi->s_NSSAI.sD = calloc(1, sizeof(NGAP_SD_t)); + ssi->s_NSSAI.sD->buf = calloc(3, sizeof(uint8_t)); + ssi->s_NSSAI.sD->size = 3; + ssi->s_NSSAI.sD->buf[0] = instance_p->s_nssai[i][si].sD[0]; + ssi->s_NSSAI.sD->buf[1] = instance_p->s_nssai[i][si].sD[1]; + ssi->s_NSSAI.sD->buf[2] = instance_p->s_nssai[i][si].sD[2]; + } + + + ASN_SEQUENCE_ADD(&plmn->tAISliceSupportList.list, ssi); + } + + ASN_SEQUENCE_ADD(&ta->broadcastPLMNList.list, plmn); + } + } + ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAList.list, ta); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (NGAP_NGSetupRequestIEs_t *)calloc(1, sizeof(NGAP_NGSetupRequestIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_DefaultPagingDRX; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_NGSetupRequestIEs__value_PR_PagingDRX; + ie->value.choice.PagingDRX = instance_p->default_drx; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &len) < 0) { + NGAP_ERROR("Failed to encode NG setup request\n"); + return -1; + } + + /* Non UE-Associated signalling -> stream = 0 */ + ngap_gNB_itti_send_sctp_data_req(instance_p->instance, ngap_amf_data_p->assoc_id, buffer, len, 0); + return ret; +} + + + + diff --git a/openair3/NGAP/ngap_gNB.h b/openair3/NGAP/ngap_gNB.h new file mode 100644 index 0000000000..e6a24acdb4 --- /dev/null +++ b/openair3/NGAP/ngap_gNB.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file ngap_gNB.h + * \brief NGAP gNB task + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + +#include +#include + +/** @defgroup _ngap_impl_ NGAP Layer Reference Implementation for gNB + * @ingroup _ref_implementation_ + * @{ + */ + +#ifndef NGAP_GNB_H_ +#define NGAP_GNB_H_ + +typedef struct ngap_gNB_config_s { + // MME related params + unsigned char amf_enabled; ///< AMF enabled ? + unsigned char ngap_enabled; ///< NGAP enabled ? +} ngap_gNB_config_t; + +extern ngap_gNB_config_t ngap_config; + +#define AMF_MODE_ENABLED ngap_config.amf_enabled +#define NGAP_CONF_MODE ngap_config.ngap_enabled + + +void *ngap_gNB_process_itti_msg(void*); +void ngap_gNB_init(void); +void *ngap_gNB_task(void *arg); + +uint32_t ngap_generate_gNB_id(void); + +#endif /* NGAP_GNB_H_ */ + +/** + * @} + */ diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c new file mode 100644 index 0000000000..73e4498f19 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -0,0 +1,287 @@ +/* + * 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 ngap_gNB_context_management_procedures.c + * \brief NGAP context management procedures + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" + +#include "ngap_gNB_itti_messaging.h" + +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_nnsf.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_nas_procedures.h" +#include "ngap_gNB_management_procedures.h" +#include "ngap_gNB_context_management_procedures.h" +#include "NGAP_PDUSessionResourceItemCxtRelReq.h" +#include "msc.h" + + +int ngap_ue_context_release_complete(instance_t instance, + ngap_ue_release_complete_t *ue_release_complete_p) +{ + + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_UEContextReleaseComplete_t *out; + NGAP_UEContextReleaseComplete_IEs_t *ie; + uint8_t *buffer; + uint32_t length; + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + + DevAssert(ue_release_complete_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + /*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) { + NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n", + ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id, + ue_context_p->ue_state); + }*/ + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + ue_release_complete_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", + ue_release_complete_p->gNB_ue_ngap_id); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = CALLOC(1, sizeof(struct NGAP_SuccessfulOutcome)); + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_UEContextRelease; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_UEContextReleaseComplete; + out = &pdu.choice.successfulOutcome->value.choice.UEContextReleaseComplete; + + /* mandatory */ + ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (NGAP_UEContextReleaseComplete_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseComplete_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UEContextReleaseComplete_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_release_complete_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Encode procedure has failed... */ + NGAP_ERROR("Failed to encode UE context release complete\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + buffer, + length, + MSC_AS_TIME_FMT" UEContextRelease successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %lu", + 0,0, //MSC_AS_TIME_ARGS(ctxt_pP), + ue_release_complete_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + //LG ngap_gNB_itti_send_sctp_close_association(ngap_gNB_instance_p->instance, + // ue_context_p->amf_ref->assoc_id); + // release UE context + struct ngap_gNB_ue_context_s *ue_context2_p = NULL; + + if ((ue_context2_p = RB_REMOVE(ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head, ue_context_p)) + != NULL) { + NGAP_WARN("Removed UE context gNB_ue_ngap_id %u\n", + ue_context2_p->gNB_ue_ngap_id); + ngap_gNB_free_ue_context(ue_context2_p); + } else { + NGAP_WARN("Removing UE context gNB_ue_ngap_id %u: did not find context\n", + ue_context_p->gNB_ue_ngap_id); + } + /*RB_FOREACH(ue_context_p, ngap_ue_map, &ngap_gNB_instance_p->ngap_ue_head) { + NGAP_WARN("in ngap_ue_map: UE context gNB_ue_ngap_id %u amf_ue_ngap_id %u state %u\n", + ue_context_p->gNB_ue_ngap_id, ue_context_p->amf_ue_ngap_id, + ue_context_p->ue_state); + }*/ + + return 0; +} + + +int ngap_ue_context_release_req(instance_t instance, + ngap_ue_release_req_t *ue_release_req_p) +{ + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_UEContextReleaseRequest_t *out; + NGAP_UEContextReleaseRequest_IEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + + DevAssert(ue_release_req_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + ue_release_req_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", + ue_release_req_p->gNB_ue_ngap_id); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = CALLOC(1, sizeof(struct NGAP_InitiatingMessage)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UEContextReleaseRequest; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UEContextReleaseRequest; + out = &pdu.choice.initiatingMessage->value.choice.UEContextReleaseRequest; + + /* mandatory */ + ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_release_req_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (ue_release_req_p->nb_of_pdusessions > 0) { + ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceListCxtRelReq; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_PDUSessionResourceListCxtRelReq; + for (int i = 0; i < ue_release_req_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceItemCxtRelReq_t *item; + item = (NGAP_PDUSessionResourceItemCxtRelReq_t *)calloc(1,sizeof(NGAP_PDUSessionResourceItemCxtRelReq_t)); + item->pDUSessionID = ue_release_req_p->pdusessions[i].pdusession_id; + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceListCxtRelReq.list, item); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* mandatory */ + ie = (NGAP_UEContextReleaseRequest_IEs_t *)calloc(1, sizeof(NGAP_UEContextReleaseRequest_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_Cause; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UEContextReleaseRequest_IEs__value_PR_Cause; + + switch (ue_release_req_p->cause) { + case NGAP_Cause_PR_radioNetwork: + ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = ue_release_req_p->cause_value; + break; + + case NGAP_Cause_PR_transport: + ie->value.choice.Cause.present = NGAP_Cause_PR_transport; + ie->value.choice.Cause.choice.transport = ue_release_req_p->cause_value; + break; + + case NGAP_Cause_PR_nas: + ie->value.choice.Cause.present = NGAP_Cause_PR_nas; + ie->value.choice.Cause.choice.nas = ue_release_req_p->cause_value; + break; + + case NGAP_Cause_PR_protocol: + ie->value.choice.Cause.present = NGAP_Cause_PR_protocol; + ie->value.choice.Cause.choice.protocol = ue_release_req_p->cause_value; + break; + + case NGAP_Cause_PR_misc: + ie->value.choice.Cause.present = NGAP_Cause_PR_misc; + ie->value.choice.Cause.choice.misc = ue_release_req_p->cause_value; + break; + + case NGAP_Cause_PR_NOTHING: + default: + ie->value.choice.Cause.present = NGAP_Cause_PR_NOTHING; + break; + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Encode procedure has failed... */ + NGAP_ERROR("Failed to encode UE context release complete\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + buffer, + length, + MSC_AS_TIME_FMT" UEContextReleaseRequest initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %lu", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_release_req_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; +} + diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.h b/openair3/NGAP/ngap_gNB_context_management_procedures.h new file mode 100644 index 0000000000..5eca34e56d --- /dev/null +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.h @@ -0,0 +1,41 @@ +/* + * 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 ngap_gNB_context_management_procedures.h + * \brief NGAP context management procedures + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + +#ifndef NGAP_GNB_CONTEXT_MANAGEMENT_PROCEDURES_H_ +#define NGAP_GNB_CONTEXT_MANAGEMENT_PROCEDURES_H_ + + +int ngap_ue_context_release_complete(instance_t instance, + ngap_ue_release_complete_t *ue_release_complete_p); + +int ngap_ue_context_release_req(instance_t instance, + ngap_ue_release_req_t *ue_release_req_p); + +#endif /* NGAP_GNB_CONTEXT_MANAGEMENT_PROCEDURES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_decoder.c b/openair3/NGAP/ngap_gNB_decoder.c new file mode 100644 index 0000000000..b551471a84 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_decoder.c @@ -0,0 +1,188 @@ +/* + * 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 ngap_gNB_decoder.c + * \brief ngap pdu decode procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + + +#include + +#include "assertions.h" + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_decoder.h" + +static int ngap_gNB_decode_initiating_message(NGAP_NGAP_PDU_t *pdu) { + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage->procedureCode) { + case NGAP_ProcedureCode_id_DownlinkNASTransport: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_InitialContextSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_UEContextRelease: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_Paging: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + NGAP_INFO("Paging initiating message\n"); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("PDUSESSIONSetup initiating message\n"); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceModify: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("PDUSESSIONModify initiating message\n"); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceRelease: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("TODO PDUSESSIONRelease initiating message\n"); + break; + + case NGAP_ProcedureCode_id_ErrorIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("TODO ErrorIndication initiating message\n"); + break; + + default: + NGAP_ERROR("Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + + return 0; +} + +static int ngap_gNB_decode_successful_outcome(NGAP_NGAP_PDU_t *pdu) { + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome->procedureCode) { + case NGAP_ProcedureCode_id_NGSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_PathSwitchRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + + default: + NGAP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.successfulOutcome->procedureCode); + return -1; + } + + return 0; +} + +static int ngap_gNB_decode_unsuccessful_outcome(NGAP_NGAP_PDU_t *pdu) { + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome->procedureCode) { + case NGAP_ProcedureCode_id_NGSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + case NGAP_ProcedureCode_id_PathSwitchRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + default: + NGAP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + return 0; +} + +int ngap_gNB_decode_pdu(NGAP_NGAP_PDU_t *pdu, const uint8_t *const buffer, + const uint32_t length) { + asn_dec_rval_t dec_ret; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + dec_ret = aper_decode(NULL, + &asn_DEF_NGAP_NGAP_PDU, + (void **)&pdu, + buffer, + length, + 0, + 0); + + if (dec_ret.code != RC_OK) { + NGAP_ERROR("Failed to decode pdu\n"); + return -1; + } + + switch(pdu->present) { + case NGAP_NGAP_PDU_PR_initiatingMessage: + return ngap_gNB_decode_initiating_message(pdu); + + case NGAP_NGAP_PDU_PR_successfulOutcome: + return ngap_gNB_decode_successful_outcome(pdu); + + case NGAP_NGAP_PDU_PR_unsuccessfulOutcome: + return ngap_gNB_decode_unsuccessful_outcome(pdu); + + default: + NGAP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + return -1; +} diff --git a/common/utils/itti_analyzer/libparser/enum_type.h b/openair3/NGAP/ngap_gNB_decoder.h similarity index 65% rename from common/utils/itti_analyzer/libparser/enum_type.h rename to openair3/NGAP/ngap_gNB_decoder.h index 4538829e78..9fc8d433c4 100644 --- a/common/utils/itti_analyzer/libparser/enum_type.h +++ b/openair3/NGAP/ngap_gNB_decoder.h @@ -18,20 +18,20 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ +/*! \file ngap_gNB_decoder.h + * \brief ngap pdu decode procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ -#include "types.h" +#include -#ifndef ENUM_TYPE_H_ -#define ENUM_TYPE_H_ +#ifndef NGAP_GNB_DECODER_H_ +#define NGAP_GNB_DECODER_H_ -char *enum_type_get_name_from_value(types_t *type, uint32_t value); +int ngap_gNB_decode_pdu(NGAP_NGAP_PDU_t *pdu, const uint8_t *const buffer, + const uint32_t length) __attribute__ ((warn_unused_result)); -int enum_type_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int enum_type_file_print(types_t *type, int indent, FILE *file); - -int enum_type_hr_display(types_t *type, int indent); - -#endif /* ENUM_TYPE_H_ */ +#endif /* NGAP_GNB_DECODER_H_ */ diff --git a/common/utils/itti_analyzer/common/logs.h b/openair3/NGAP/ngap_gNB_default_values.h similarity index 61% rename from common/utils/itti_analyzer/common/logs.h rename to openair3/NGAP/ngap_gNB_default_values.h index bd901cc394..afbe91ec7f 100644 --- a/common/utils/itti_analyzer/common/logs.h +++ b/openair3/NGAP/ngap_gNB_default_values.h @@ -18,39 +18,28 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -/* - * logs.h - * - * Created on: Nov 22, 2013 - * Author: Laurent Winckel +/*! \file ngap_gNB_default_values.h + * \brief ngap default values + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 */ -#ifndef LOGS_H_ -#define LOGS_H_ +#ifndef NGAP_GNB_DEFAULT_VALUES_H_ +#define NGAP_GNB_DEFAULT_VALUES_H_ -/* Added definition of the g_info log function to complete the set of log functions from "gmessages.h" */ +#define GNB_TAC (1) +#define GNB_MCC (208) +#define GNB_MNC (92) -#include +#define GNB_NAME "Eurecom GNB" +#define GNB_NAME_FORMAT (GNB_NAME" %u") -#ifdef G_HAVE_ISO_VARARGS +#define NGAP_PORT_NUMBER (38412) +#define NGAP_SCTP_PPID (60) -#define g_info(...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_INFO, \ - __VA_ARGS__) +#define X2AP_PORT_NUMBER (36422) +#define X2AP_SCTP_PPID (27) -#else - -static void -g_info (const gchar *format, - ...) -{ - va_list args; - va_start (args, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, format, args); - va_end (args); -} - -#endif - -#endif /* LOGS_H_ */ +#endif /* NGAP_GNB_DEFAULT_VALUES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_defs.h b/openair3/NGAP/ngap_gNB_defs.h new file mode 100644 index 0000000000..f2bdd646ae --- /dev/null +++ b/openair3/NGAP/ngap_gNB_defs.h @@ -0,0 +1,298 @@ +/* + * 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 ngap_gNB_defs.h + * \brief ngap define procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +#include + +#include "queue.h" +#include "tree.h" + +#ifndef NGAP_GNB_DEFS_H_ +#define NGAP_GNB_DEFS_H_ + +#define NGAP_GNB_NAME_LENGTH_MAX (150) + +typedef enum { + /* Disconnected state: initial state for any association. */ + NGAP_GNB_STATE_DISCONNECTED = 0x0, + /* State waiting for S1 Setup response message if gNB is AMF accepted or + * S1 Setup failure if AMF rejects the gNB. + */ + NGAP_GNB_STATE_WAITING = 0x1, + /* The gNB is successfully connected to AMF, UE contexts can be created. */ + NGAP_GNB_STATE_CONNECTED = 0x2, + /* The AMF has sent an overload start message. Once the AMF disables the + * OVERLOAD marker, the state of the association will be + * NGAP_GNB_STATE_CONNECTED. + */ + NGAP_GNB_OVERLOAD = 0x3, + /* Max number of states available */ + NGAP_GNB_STATE_MAX, +} ngap_gNB_state_t; + +/* If the Overload Action IE in the OVERLOAD START message is set to + * - “reject all RRC connection establishments for non-emergency mobile + * originated data transfer  E(i.e. reject traffic corresponding to RRC cause + * “mo-data  E(TS 36.331 [16])), or + * - “reject all RRC connection establishments for signalling  E(i.e. reject + * traffic corresponding to RRC cause “modata Eand “mo-signalling E * (TS 38.331 [16])),or + * - “only permit RRC connection establishments for emergency sessions and + * mobile terminated services E(i.e. only permit traffic corresponding to RRC + * cause “emergency Eand “mt-Access E(TS 36.331 [16])). + * + * NOTE: When the Overload Action IE is set to “only permit RRC connection + * establishments for emergency sessions and mobile terminated services E + * emergency calls with RRC cause “highPriorityAcess Efrom high priority users + * are rejected (TS 24.301 [24]). + */ +typedef enum { + NGAP_OVERLOAD_REJECT_MO_DATA = 0x0, + NGAP_OVERLOAD_REJECT_ALL_SIGNALLING = 0x1, + NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT = 0x2, + NGAP_NO_OVERLOAD = 0x3, + NGAP_OVERLOAD_MAX, +} ngap_overload_state_t; + +/* Served PLMN identity element */ +struct plmn_identity_s { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + STAILQ_ENTRY(plmn_identity_s) next; +}; + +/* Served amf region id for a particular AMF */ +struct served_region_id_s { + uint8_t amf_region_id; + STAILQ_ENTRY(served_region_id_s) next; +}; + +/* Served amf set id for a particular AMF */ +struct amf_set_id_s { + uint16_t amf_set_id; + STAILQ_ENTRY(amf_set_id_s) next; +}; + +/* Served amf pointer for a particular AMF */ +struct amf_pointer_s { + uint8_t amf_pointer; + STAILQ_ENTRY(amf_pointer_s) next; +}; + + +/* Served guami element */ +struct served_guami_s { + /* Number of AMF served PLMNs */ + uint8_t nb_served_plmns; + /* List of served PLMNs by AMF */ + STAILQ_HEAD(served_plmns_s, plmn_identity_s) served_plmns; + + /* Number of region id in list */ + uint8_t nb_region_id; + /* Served group id list */ + STAILQ_HEAD(served_region_ids_s, served_region_id_s) served_region_ids; + + /* Number of AMF set id */ + uint8_t nb_amf_set_id; + /* AMF Set id to uniquely identify an AMF within an AMF pool area */ + STAILQ_HEAD(amf_set_ids_s, amf_set_id_s) amf_set_ids; + + /* Number of AMF pointer */ + uint8_t nb_amf_pointer; + /* AMF pointer to uniquely identify an AMF within an AMF pool area */ + STAILQ_HEAD(amf_pointers_s, amf_pointer_s) amf_pointers; + + /* Next GUAMI element */ + STAILQ_ENTRY(served_guami_s) next; +}; + +/* NSSAI element */ +struct slice_support_s{ + uint8_t sST; + uint8_t sD_flag; + uint8_t sD[3]; + + /* Next slice element */ + STAILQ_ENTRY(slice_support_s) next; +}; + + +/* plmn support element */ +struct plmn_support_s { + struct plmn_identity_s plmn_identity; + + /* Number of slice support in list */ + uint8_t nb_slice_s; + /* Served group id list */ + STAILQ_HEAD(slice_supports_s, slice_support_s) slice_supports; + + /* Next plmn support element */ + STAILQ_ENTRY(plmn_support_s) next; +}; + + +struct ngap_gNB_instance_s; + +/* This structure describes association of a gNB to a AMF */ +typedef struct ngap_gNB_amf_data_s { + /* AMF descriptors tree, ordered by sctp assoc id */ + RB_ENTRY(ngap_gNB_amf_data_s) entry; + + /* This is the optional name provided by the AMF */ + char *amf_name; + + /* AMF NGAP IP address */ + net_ip_address_t amf_s1_ip; + + /* List of served GUAMI per AMF. There is one GUAMI per RAT with a max + * number of 8 RATs but in our case only one is used. The LTE related pool + * configuration is included on the first place in the list. + */ + STAILQ_HEAD(served_guamis_s, served_guami_s) served_guami; + + /* Relative processing capacity of an AMF with respect to the other AMFs + * in the pool in order to load-balance AMFs within a pool as defined + * in TS 23.401. + */ + uint8_t relative_amf_capacity; + + /* + * List of PLMN Support per AMF. + * + */ + STAILQ_HEAD(plmn_supports_s, plmn_support_s) plmn_supports; + + /* Current AMF overload information (if any). */ + ngap_overload_state_t overload_state; + /* Current gNB->AMF NGAP association state */ + ngap_gNB_state_t state; + + /* Next usable stream for UE signalling */ + int32_t nextstream; + + /* Number of input/ouput streams */ + uint16_t in_streams; + uint16_t out_streams; + + /* Connexion id used between SCTP/NGAP */ + uint16_t cnx_id; + + /* SCTP association id */ + int32_t assoc_id; + + /* This is served PLMN IDs communicated to the AMF via an index over the + * MCC/MNC array in ngap_gNB_instance */ + uint8_t broadcast_plmn_num; + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]; + + + /* Only meaningfull in virtual mode */ + struct ngap_gNB_instance_s *ngap_gNB_instance; +} ngap_gNB_amf_data_t; + +typedef struct ngap_gNB_NSSAI_s{ + uint8_t sST; + uint8_t sD_flag; + uint8_t sD[3]; +}ngap_gNB_NSSAI_t; + +typedef struct ngap_gNB_instance_s { + /* Next ngap gNB association. + * Only used for virtual mode. + */ + STAILQ_ENTRY(ngap_gNB_instance_s) ngap_gNB_entries; + + /* Number of AMF requested by gNB (tree size) */ + uint32_t ngap_amf_nb; + /* Number of AMF for which association is pending */ + uint32_t ngap_amf_pending_nb; + /* Number of AMF successfully associated to gNB */ + uint32_t ngap_amf_associated_nb; + /* Tree of NGAP AMF associations ordered by association ID */ + RB_HEAD(ngap_amf_map, ngap_gNB_amf_data_s) ngap_amf_head; + + /* TODO: add a map ordered by relative AMF capacity */ + + /* Tree of UE ordered by gNB_ue_ngap_id's */ + RB_HEAD(ngap_ue_map, ngap_gNB_ue_context_s) ngap_ue_head; + + /* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */ + instance_t instance; + + /* Displayable name of gNB */ + char *gNB_name; + + /* Unique gNB_id to identify the gNB within EPC. + * In our case the gNB is a macro gNB so the id will be 20 bits long. + * For Home gNB id, this field should be 36 bits long. + */ + uint32_t gNB_id; + /* The type of the cell */ + enum cell_type_e cell_type; + + /* Tracking area code */ + uint32_t tac; + + /* gNB NGAP IP address */ + net_ip_address_t gNB_ng_ip; + + /* Mobile Country Code + * Mobile Network Code + */ + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; + + uint16_t num_nssai[PLMN_LIST_MAX_SIZE]; + ngap_gNB_NSSAI_t s_nssai[PLMN_LIST_MAX_SIZE][8]; + + /* Default Paging DRX of the gNB as defined in TS 38.304 */ + ngap_paging_drx_t default_drx; +} ngap_gNB_instance_t; + +typedef struct { + /* List of served gNBs + * Only used for virtual mode + */ + STAILQ_HEAD(ngap_gNB_instances_head_s, ngap_gNB_instance_s) ngap_gNB_instances_head; + /* Nb of registered gNBs */ + uint8_t nb_registered_gNBs; + + /* Generate a unique connexion id used between NGAP and SCTP */ + uint16_t global_cnx_id; +} ngap_gNB_internal_data_t; + +int ngap_gNB_compare_assoc_id( + struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2); + +/* Generate the tree management functions */ +RB_PROTOTYPE(ngap_amf_map, ngap_gNB_amf_data_s, entry, + ngap_gNB_compare_assoc_id); + +#endif /* NGAP_GNB_DEFS_H_ */ diff --git a/openair3/NGAP/ngap_gNB_encoder.c b/openair3/NGAP/ngap_gNB_encoder.c new file mode 100644 index 0000000000..c69de32467 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_encoder.c @@ -0,0 +1,223 @@ +/* + * 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 ngap_gNB_encoder.c + * \brief ngap pdu encode procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" +#include "intertask_interface.h" +#include "ngap_common.h" +#include "ngap_gNB_encoder.h" + +static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, + uint8_t **buffer, + uint32_t *len); + +static inline int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, + uint8_t **buffer, uint32_t *len); + +static inline int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, + uint8_t **buffer, uint32_t *len); + +int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) { + int ret = -1; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + switch(pdu->present) { + case NGAP_NGAP_PDU_PR_initiatingMessage: + ret = ngap_gNB_encode_initiating(pdu, buffer, len); + break; + + case NGAP_NGAP_PDU_PR_successfulOutcome: + ret = ngap_gNB_encode_successfull_outcome(pdu, buffer, len); + break; + + case NGAP_NGAP_PDU_PR_unsuccessfulOutcome: + ret = ngap_gNB_encode_unsuccessfull_outcome(pdu, buffer, len); + break; + + default: + NGAP_DEBUG("Unknown message outcome (%d) or not implemented", + (int)pdu->present); + return -1; + } + + //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, pdu); + return ret; +} + +static inline +int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, + uint8_t **buffer, uint32_t *len) { + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.initiatingMessage->procedureCode) { + case NGAP_ProcedureCode_id_NGSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_UplinkNASTransport: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_InitialUEMessage: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_NASNonDeliveryIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_UEContextReleaseRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_PathSwitchRequest: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceModifyIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + default: + NGAP_DEBUG("Unknown procedure ID (%d) for initiating message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline +int ngap_gNB_encode_successfull_outcome(NGAP_NGAP_PDU_t *pdu, + uint8_t **buffer, uint32_t *len) { + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.successfulOutcome->procedureCode) { + case NGAP_ProcedureCode_id_InitialContextSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_UEContextRelease: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("PDUSESSIONSetup successful message\n"); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceModify: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("PDUSESSIONModify successful message\n"); + break; + + case NGAP_ProcedureCode_id_PDUSessionResourceRelease: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("PDUSESSION Release successful message\n"); + break; + + default: + NGAP_WARN("Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.successfulOutcome->procedureCode); + return -1; + } + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline +int ngap_gNB_encode_unsuccessfull_outcome(NGAP_NGAP_PDU_t *pdu, + uint8_t **buffer, uint32_t *len) { + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + DevAssert(pdu != NULL); + + switch(pdu->choice.unsuccessfulOutcome->procedureCode) { + case NGAP_ProcedureCode_id_InitialContextSetup: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + break; + + default: + NGAP_DEBUG("Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, (void *)pdu); + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_NGAP_PDU, pdu); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} diff --git a/common/utils/itti_analyzer/libparser/array_type.h b/openair3/NGAP/ngap_gNB_encoder.h similarity index 68% rename from common/utils/itti_analyzer/libparser/array_type.h rename to openair3/NGAP/ngap_gNB_encoder.h index b336934dbb..bd151405ff 100644 --- a/common/utils/itti_analyzer/libparser/array_type.h +++ b/openair3/NGAP/ngap_gNB_encoder.h @@ -19,17 +19,18 @@ * contact@openairinterface.org */ -#include "types.h" +/*! \file ngap_gNB_encoder.h + * \brief ngap pdu encode procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +#ifndef NGAP_GNB_ENCODER_H_ +#define NGAP_GNB_ENCODER_H_ -#ifndef ARRAY_TYPE_H_ -#define ARRAY_TYPE_H_ +int ngap_gNB_encode_pdu(NGAP_NGAP_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +__attribute__ ((warn_unused_result)); -int array_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int array_type_hr_display(types_t *type, int indent); - -int array_type_file_print(types_t *type, int indent, FILE *file); - -#endif /* ARRAY_TYPE_H_ */ +#endif /* NGAP_GNB_ENCODER_H_ */ diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c new file mode 100644 index 0000000000..f143002537 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -0,0 +1,1900 @@ +/* + * 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 ngap_gNB_handlers.c + * \brief ngap messages handlers for gNB part + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +#include + +#include "intertask_interface.h" + +#include "asn1_conversions.h" + +#include "ngap_common.h" +// #include "ngap_gNB.h" +#include "ngap_gNB_defs.h" +#include "ngap_gNB_handlers.h" +#include "ngap_gNB_decoder.h" + +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_trace.h" +#include "ngap_gNB_nas_procedures.h" +#include "ngap_gNB_management_procedures.h" + +#include "ngap_gNB_default_values.h" + +#include "assertions.h" +#include "conversions.h" +#include "msc.h" +#include "NGAP_NonDynamic5QIDescriptor.h" + +static +int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); +static +int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_error_indication(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_paging(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_ng_path_switch_request_ack(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_ng_path_switch_request_failure(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +static +int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +/* Handlers matrix. Only gNB related procedure present here */ +ngap_message_decoded_callback ngap_messages_callback[][3] = { + { 0, 0, 0 }, /* AMFConfigurationUpdate */ + { 0, 0, 0 }, /* AMFStatusIndication */ + { 0, 0, 0 }, /* CellTrafficTrace */ + { ngap_gNB_handle_deactivate_trace, 0, 0 }, /* DeactivateTrace */ + { ngap_gNB_handle_nas_downlink, 0, 0 }, /* DownlinkNASTransport */ + { 0, 0, 0 }, /* DownlinkNonUEAssociatedNRPPaTransport */ + { 0, 0, 0 }, /* DownlinkRANConfigurationTransfer */ + { 0, 0, 0 }, /* DownlinkRANStatusTransfer */ + { 0, 0, 0 }, /* DownlinkUEAssociatedNRPPaTransport */ + { ngap_gNB_handle_error_indication, 0, 0 }, /* ErrorIndication */ + { 0, 0, 0 }, /* HandoverCancel */ + { 0, 0, 0 }, /* HandoverNotification */ + { 0, 0, 0 }, /* HandoverPreparation */ + { 0, 0, 0 }, /* HandoverResourceAllocation */ + { ngap_gNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */ + { 0, 0, 0 }, /* InitialUEMessage */ + { 0, 0, 0 }, /* LocationReportingControl */ + { 0, 0, 0 }, /* LocationReportingFailureIndication */ + { 0, 0, 0 }, /* LocationReport */ + { 0, 0, 0 }, /* NASNonDeliveryIndication */ + { 0, 0, 0 }, /* NGReset */ + { 0, ngap_gNB_handle_ng_setup_response, ngap_gNB_handle_ng_setup_failure }, /* NGSetup */ + { 0, 0, 0 }, /* OverloadStart */ + { 0, 0, 0 }, /* OverloadStop */ + { ngap_gNB_handle_paging, 0, 0 }, /* Paging */ + { 0, ngap_gNB_handle_ng_path_switch_request_ack, ngap_gNB_handle_ng_path_switch_request_failure }, /* PathSwitchRequest */ + { ngap_gNB_handle_pdusession_modify_request, 0, 0 }, /* PDUSessionResourceModify */ + { 0, ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm, 0 }, /* PDUSessionResourceModifyIndication */ + { ngap_gNB_handle_pdusession_release_command, 0, 0 }, /* PDUSessionResourceRelease */ + { ngap_gNB_handle_pdusession_setup_request, 0, 0 }, /* PDUSessionResourceSetup */ + { 0, 0, 0 }, /* PDUSessionResourceNotify */ + { 0, 0, 0 }, /* PrivateMessage */ + { 0, 0, 0 }, /* PWSCancel */ + { 0, 0, 0 }, /* PWSFailureIndication */ + { 0, 0, 0 }, /* PWSRestartIndication */ + { 0, 0, 0 }, /* RANConfigurationUpdate */ + { 0, 0, 0 }, /* RerouteNASRequest */ + { 0, 0, 0 }, /* RRCInactiveTransitionReport */ + { 0, 0, 0 }, /* TraceFailureIndication */ + { ngap_gNB_handle_trace_start, 0, 0 }, /* TraceStart */ + { 0, 0, 0 }, /* UEContextModification */ + { ngap_gNB_handle_ue_context_release_command, 0, 0 }, /* UEContextRelease */ + { 0, 0, 0 }, /* UEContextReleaseRequest */ + { 0, 0, 0 }, /* UERadioCapabilityCheck */ + { 0, 0, 0 }, /* UERadioCapabilityInfoIndication */ + { 0, 0, 0 }, /* UETNLABindingRelease */ + { 0, 0, 0 }, /* UplinkNASTransport */ + { 0, 0, 0 }, /* UplinkNonUEAssociatedNRPPaTransport */ + { 0, 0, 0 }, /* UplinkRANConfigurationTransfer */ + { 0, 0, 0 }, /* UplinkRANStatusTransfer */ + { 0, 0, 0 }, /* UplinkUEAssociatedNRPPaTransport */ + { 0, 0, 0 }, /* WriteReplaceWarning */ + { 0, 0, 0 }, /* SecondaryRATDataUsageReport */ + +}; +char *ngap_direction2String(int ngap_dir) { + static char *ngap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ + }; + return(ngap_direction_String[ngap_dir]); +} +void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shutdown) { + if (sctp_shutdown) { + /* A previously connected AMF has been shutdown */ + + /* TODO check if it was used by some gNB and send a message to inform these gNB if there is no more associated AMF */ + if (amf_desc_p->state == NGAP_GNB_STATE_CONNECTED) { + amf_desc_p->state = NGAP_GNB_STATE_DISCONNECTED; + + if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb > 0) { + /* Decrease associated AMF number */ + amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb --; + } + + /* If there are no more associated AMF, inform gNB app */ + if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb == 0) { + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DEREGISTERED_GNB_IND); + NGAP_DEREGISTERED_GNB_IND(message_p).nb_amf = 0; + itti_send_msg_to_task(TASK_GNB_APP, amf_desc_p->ngap_gNB_instance->instance, message_p); + } + } + } else { + /* Check that at least one setup message is pending */ + DevCheck(amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb > 0, amf_desc_p->ngap_gNB_instance->instance, + amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb, 0); + + if (amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb > 0) { + /* Decrease pending messages number */ + amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb --; + } + + /* If there are no more pending messages, inform gNB app */ + if (amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb == 0) { + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_REGISTER_GNB_CNF); + NGAP_REGISTER_GNB_CNF(message_p).nb_amf = amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb; + itti_send_msg_to_task(TASK_GNB_APP, amf_desc_p->ngap_gNB_instance->instance, message_p); + } + } +} + +int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream, + const uint8_t *const data, const uint32_t data_length) { + NGAP_NGAP_PDU_t pdu; + int ret; + DevAssert(data != NULL); + memset(&pdu, 0, sizeof(pdu)); + + if (ngap_gNB_decode_pdu(&pdu, data, data_length) < 0) { + NGAP_ERROR("Failed to decode PDU\n"); + return -1; + } + + /* Checking procedure Code and direction of message */ + if (pdu.choice.initiatingMessage->procedureCode >= sizeof(ngap_messages_callback) / (3 * sizeof( + ngap_message_decoded_callback)) + || (pdu.present > NGAP_NGAP_PDU_PR_unsuccessfulOutcome)) { + NGAP_ERROR("[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n", + assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for gNB (wrong direction). + */ + if (ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + NGAP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n", + assoc_id, pdu.choice.initiatingMessage->procedureCode, + ngap_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + + /* Calling the right handler */ + ret = (*ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1]) + (assoc_id, stream, &pdu); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return ret; +} + +static +int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + NGAP_NGSetupFailure_t *container; + NGAP_NGSetupFailureIEs_t *ie; + ngap_gNB_amf_data_t *amf_desc_p; + DevAssert(pdu != NULL); + container = &pdu->choice.unsuccessfulOutcome->value.choice.NGSetupFailure; + + /* S1 Setup Failure == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + NGAP_WARN("[SCTP %d] Received s1 setup failure on stream != 0 (%d)\n", + assoc_id, stream); + } + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received S1 setup response for non existing " + "AMF context\n", assoc_id); + return -1; + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupFailureIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_Cause,true); + + if ((ie->value.choice.Cause.present == NGAP_Cause_PR_misc) && + (ie->value.choice.Cause.choice.misc == NGAP_CauseMisc_unspecified)) { + NGAP_WARN("Received NG setup failure for AMF... AMF is not ready\n"); + } else { + NGAP_ERROR("Received NG setup failure for AMF... please check your parameters\n"); + } + + amf_desc_p->state = NGAP_GNB_STATE_WAITING; + ngap_handle_ng_setup_message(amf_desc_p, 0); + return 0; +} + +static +int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + NGAP_NGSetupResponse_t *container; + NGAP_NGSetupResponseIEs_t *ie; + ngap_gNB_amf_data_t *amf_desc_p; + int i; + DevAssert(pdu != NULL); + container = &pdu->choice.successfulOutcome->value.choice.NGSetupResponse; + + /* NG Setup Response == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + NGAP_ERROR("[SCTP %d] Received ng setup response on stream != 0 (%d)\n", + assoc_id, stream); + return -1; + } + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NG setup response for non existing " + "AMF context\n", assoc_id); + return -1; + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_ServedGUAMIList, true); + + /* The list of served guami can contain at most 256 elements. + * NR related guami is the first element in the list, i.e with an id of 0. + */ + NGAP_DEBUG("servedGUAMIs.list.count %d\n", ie->value.choice.ServedGUAMIList.list.count); + DevAssert(ie->value.choice.ServedGUAMIList.list.count > 0); + DevAssert(ie->value.choice.ServedGUAMIList.list.count <= NGAP_maxnoofServedGUAMIs); + + for (i = 0; i < ie->value.choice.ServedGUAMIList.list.count; i++) { + NGAP_ServedGUAMIItem_t *guami_item_p; + struct served_guami_s *new_guami_p; + + guami_item_p = ie->value.choice.ServedGUAMIList.list.array[i]; + new_guami_p = calloc(1, sizeof(struct served_guami_s)); + STAILQ_INIT(&new_guami_p->served_plmns); + STAILQ_INIT(&new_guami_p->served_region_ids); + STAILQ_INIT(&new_guami_p->amf_set_ids); + STAILQ_INIT(&new_guami_p->amf_pointers); + + NGAP_PLMNIdentity_t *plmn_identity_p; + struct plmn_identity_s *new_plmn_identity_p; + plmn_identity_p = &guami_item_p->gUAMI.pLMNIdentity; + new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s)); + TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc, + new_plmn_identity_p->mnc, new_plmn_identity_p->mnc_digit_length); + STAILQ_INSERT_TAIL(&new_guami_p->served_plmns, new_plmn_identity_p, next); + new_guami_p->nb_served_plmns++; + + NGAP_AMFRegionID_t *amf_region_id_p; + struct served_region_id_s *new_region_id_p; + amf_region_id_p = &guami_item_p->gUAMI.aMFRegionID; + new_region_id_p = calloc(1, sizeof(struct served_region_id_s)); + OCTET_STRING_TO_INT8(amf_region_id_p, new_region_id_p->amf_region_id); + STAILQ_INSERT_TAIL(&new_guami_p->served_region_ids, new_region_id_p, next); + new_guami_p->nb_region_id++; + + NGAP_AMFSetID_t *amf_set_id_p; + struct amf_set_id_s *new_amf_set_id_p; + amf_set_id_p = &guami_item_p->gUAMI.aMFSetID; + new_amf_set_id_p = calloc(1, sizeof(struct amf_set_id_s)); + OCTET_STRING_TO_INT16(amf_set_id_p, new_amf_set_id_p->amf_set_id); + STAILQ_INSERT_TAIL(&new_guami_p->amf_set_ids, new_amf_set_id_p, next); + new_guami_p->nb_amf_set_id++; + + NGAP_AMFPointer_t *amf_pointer_p; + struct amf_pointer_s *new_amf_pointer_p; + amf_pointer_p = &guami_item_p->gUAMI.aMFPointer; + new_amf_pointer_p = calloc(1, sizeof(struct amf_pointer_s)); + OCTET_STRING_TO_INT8(amf_pointer_p, new_amf_pointer_p->amf_pointer); + STAILQ_INSERT_TAIL(&new_guami_p->amf_pointers, new_amf_pointer_p, next); + new_guami_p->nb_amf_pointer++; + + STAILQ_INSERT_TAIL(&amf_desc_p->served_guami, new_guami_p, next); + } + + /* Set the capacity of this AMF */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RelativeAMFCapacity, true); + + amf_desc_p->relative_amf_capacity = ie->value.choice.RelativeAMFCapacity; + + /* mandatory set the amf name */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMFName, true); + + if (ie) { + amf_desc_p->amf_name = calloc(ie->value.choice.AMFName.size + 1, sizeof(char)); + memcpy(amf_desc_p->amf_name, ie->value.choice.AMFName.buf, + ie->value.choice.AMFName.size); + /* Convert the amf name to a printable string */ + amf_desc_p->amf_name[ie->value.choice.AMFName.size] = '\0'; + } + + + /* mandatory set the plmn supports */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PLMNSupportList, true); + + NGAP_DEBUG("PLMNSupportList.list.count %d\n", ie->value.choice.PLMNSupportList.list.count); + DevAssert(ie->value.choice.PLMNSupportList.list.count > 0); + DevAssert(ie->value.choice.PLMNSupportList.list.count <= NGAP_maxnoofPLMNs); + + STAILQ_INIT(&amf_desc_p->plmn_supports); + + for (i = 0; i < ie->value.choice.ServedGUAMIList.list.count; i++) { + NGAP_PLMNSupportItem_t *plmn_support_item_p; + struct plmn_support_s *new_plmn_support_p; + NGAP_SliceSupportItem_t *slice_support_item_p; + struct slice_support_s *new_slice_support_p; + + plmn_support_item_p = ie->value.choice.PLMNSupportList.list.array[i]; + + new_plmn_support_p = calloc(1, sizeof(struct plmn_support_s)); + + TBCD_TO_MCC_MNC(&plmn_support_item_p->pLMNIdentity, new_plmn_support_p->plmn_identity.mcc, + new_plmn_support_p->plmn_identity.mnc, new_plmn_support_p->plmn_identity.mnc_digit_length); + + NGAP_DEBUG("PLMNSupportList.list.count %d\n", plmn_support_item_p->sliceSupportList.list.count); + DevAssert(plmn_support_item_p->sliceSupportList.list.count > 0); + DevAssert(plmn_support_item_p->sliceSupportList.list.count <= NGAP_maxnoofSliceItems); + + STAILQ_INIT(&new_plmn_support_p->slice_supports); + for(int j=0; jsliceSupportList.list.count; j++) { + slice_support_item_p = plmn_support_item_p->sliceSupportList.list.array[j]; + + new_slice_support_p = calloc(1, sizeof(struct slice_support_s)); + + OCTET_STRING_TO_INT8(&slice_support_item_p->s_NSSAI.sST, new_slice_support_p->sST); + + if(slice_support_item_p->s_NSSAI.sD != NULL) { + new_slice_support_p->sD_flag = 1; + new_slice_support_p->sD[0] = slice_support_item_p->s_NSSAI.sD->buf[0]; + new_slice_support_p->sD[1] = slice_support_item_p->s_NSSAI.sD->buf[1]; + new_slice_support_p->sD[2] = slice_support_item_p->s_NSSAI.sD->buf[2]; + } + STAILQ_INSERT_TAIL(&new_plmn_support_p->slice_supports, new_slice_support_p, next); + } + + STAILQ_INSERT_TAIL(&amf_desc_p->plmn_supports, new_plmn_support_p, next); + } + + /* The association is now ready as gNB and AMF know parameters of each other. + * Mark the association as UP to enable UE contexts creation. + */ + amf_desc_p->state = NGAP_GNB_STATE_CONNECTED; + amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb ++; + ngap_handle_ng_setup_message(amf_desc_p, 0); + + return 0; +} + + +static +int ngap_gNB_handle_error_indication(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + NGAP_ErrorIndication_t *container; + NGAP_ErrorIndicationIEs_t *ie; + ngap_gNB_amf_data_t *amf_desc_p; + uint64_t amf_ue_ngap_id; + + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.ErrorIndication; + + /* NG Setup Failure == Non UE-related procedure -> stream 0 */ + if (stream != 0) { + NGAP_WARN("[SCTP %d] Received ng Error indication on stream != 0 (%d)\n", + assoc_id, stream); + } + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received ng Error indication for non existing " + "AMF context\n", assoc_id); + return -1; + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, false); + + /* optional */ + if (ie != NULL) { + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + NGAP_WARN("Received NG Error indication AMF UE NGAP ID 0x%lx\n", amf_ue_ngap_id); + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, false); + + /* optional */ + if (ie != NULL) { + NGAP_WARN("Received NG Error indication gNB UE NGAP ID 0x%lx\n", ie->value.choice.RAN_UE_NGAP_ID); + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_Cause, false); + + /* optional */ + if (ie) { + switch(ie->value.choice.Cause.present) { + case NGAP_Cause_PR_NOTHING: + NGAP_WARN("Received NG Error indication cause NOTHING\n"); + break; + + case NGAP_Cause_PR_radioNetwork: + switch (ie->value.choice.Cause.choice.radioNetwork) { + case NGAP_CauseRadioNetwork_unspecified: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unspecified\n"); + break; + + case NGAP_CauseRadioNetwork_txnrelocoverall_expiry: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_txnrelocoverall_expiry\n"); + break; + + case NGAP_CauseRadioNetwork_successful_handover: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_successful_handover\n"); + break; + + case NGAP_CauseRadioNetwork_release_due_to_ngran_generated_reason: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_ngran_generated_reason\n"); + break; + + case NGAP_CauseRadioNetwork_release_due_to_5gc_generated_reason: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_5gc_generated_reason\n"); + break; + + case NGAP_CauseRadioNetwork_handover_cancelled: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_handover_cancelled\n"); + break; + + case NGAP_CauseRadioNetwork_partial_handover: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_partial_handover\n"); + break; + + case NGAP_CauseRadioNetwork_ho_failure_in_target_5GC_ngran_node_or_target_system: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ho_failure_in_target_5GC_ngran_node_or_target_system\n"); + break; + + case NGAP_CauseRadioNetwork_ho_target_not_allowed: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ho_target_not_allowed\n"); + break; + + case NGAP_CauseRadioNetwork_tngrelocoverall_expiry: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_tngrelocoverall_expiry\n"); + break; + + case NGAP_CauseRadioNetwork_tngrelocprep_expiry: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_tngrelocprep_expiry\n"); + break; + + case NGAP_CauseRadioNetwork_cell_not_available: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_cell_not_available\n"); + break; + + case NGAP_CauseRadioNetwork_unknown_targetID: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unknown_targetID\n"); + break; + + case NGAP_CauseRadioNetwork_no_radio_resources_available_in_target_cell: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_no_radio_resources_available_in_target_cell\n"); + break; + + case NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID\n"); + break; + + case NGAP_CauseRadioNetwork_inconsistent_remote_UE_NGAP_ID: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_inconsistent_remote_UE_NGAP_ID\n"); + break; + + case NGAP_CauseRadioNetwork_handover_desirable_for_radio_reason: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_handover_desirable_for_radio_reason\n"); + break; + + case NGAP_CauseRadioNetwork_time_critical_handover: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_time_critical_handover\n"); + break; + + case NGAP_CauseRadioNetwork_resource_optimisation_handover: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_resource_optimisation_handover\n"); + break; + + case NGAP_CauseRadioNetwork_reduce_load_in_serving_cell: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_reduce_load_in_serving_cell\n"); + break; + + case NGAP_CauseRadioNetwork_user_inactivity: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_user_inactivity\n"); + break; + + case NGAP_CauseRadioNetwork_radio_connection_with_ue_lost: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_radio_connection_with_ue_lost\n"); + break; + + case NGAP_CauseRadioNetwork_radio_resources_not_available: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_radio_resources_not_available\n"); + break; + + case NGAP_CauseRadioNetwork_invalid_qos_combination: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_invalid_qos_combination\n"); + break; + + case NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure\n"); + break; + + case NGAP_CauseRadioNetwork_interaction_with_other_procedure: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_interaction_with_other_procedure\n"); + break; + + case NGAP_CauseRadioNetwork_unknown_PDU_session_ID: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unknown_PDU_session_ID\n"); + break; + + case NGAP_CauseRadioNetwork_unkown_qos_flow_ID: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unkown_qos_flow_ID\n"); + break; + + case NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances\n"); + break; + + case NGAP_CauseRadioNetwork_multiple_qos_flow_ID_instances: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_multiple_qos_flow_ID_instances\n"); + break; + + case NGAP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported\n"); + break; + + case NGAP_CauseRadioNetwork_ng_intra_system_handover_triggered: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ng_intra_system_handover_triggered\n"); + break; + + case NGAP_CauseRadioNetwork_ng_inter_system_handover_triggered: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ng_inter_system_handover_triggered\n"); + break; + + case NGAP_CauseRadioNetwork_xn_handover_triggered: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_xn_handover_triggered\n"); + break; + + case NGAP_CauseRadioNetwork_not_supported_5QI_value: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_not_supported_5QI_value\n"); + break; + + case NGAP_CauseRadioNetwork_ue_context_transfer: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ue_context_transfer\n"); + break; + + case NGAP_CauseRadioNetwork_ims_voice_eps_fallback_or_rat_fallback_triggered: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ims_voice_eps_fallback_or_rat_fallback_triggered\n"); + break; + + case NGAP_CauseRadioNetwork_up_integrity_protection_not_possible: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_integrity_protection_not_possible\n"); + break; + case NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible\n"); + break; + + case NGAP_CauseRadioNetwork_slice_not_supported: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_slice_not_supported\n"); + break; + + case NGAP_CauseRadioNetwork_ue_in_rrc_inactive_state_not_reachable: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ue_in_rrc_inactive_state_not_reachable\n"); + break; + + case NGAP_CauseRadioNetwork_redirection: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_redirection\n"); + break; + + case NGAP_CauseRadioNetwork_resources_not_available_for_the_slice: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_resources_not_available_for_the_slice\n"); + break; + + case NGAP_CauseRadioNetwork_ue_max_integrity_protected_data_rate_reason: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ue_max_integrity_protected_data_rate_reason\n"); + break; + + case NGAP_CauseRadioNetwork_release_due_to_cn_detected_mobility: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_cn_detected_mobility\n"); + break; + + case NGAP_CauseRadioNetwork_n26_interface_not_available: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_n26_interface_not_available\n"); + break; + + case NGAP_CauseRadioNetwork_release_due_to_pre_emption: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_pre_emption\n"); + break; + + case NGAP_CauseRadioNetwork_multiple_location_reporting_reference_ID_instances: + NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_multiple_location_reporting_reference_ID_instances\n"); + break; + + default: + NGAP_WARN("Received NG Error indication cause radio network case not handled\n"); + } + + break; + + case NGAP_Cause_PR_transport: + switch (ie->value.choice.Cause.choice.transport) { + case NGAP_CauseTransport_transport_resource_unavailable: + NGAP_WARN("Received NG Error indication NGAP_CauseTransport_transport_resource_unavailable\n"); + break; + + case NGAP_CauseTransport_unspecified: + NGAP_WARN("Received NG Error indication NGAP_CauseTransport_unspecified\n"); + break; + + default: + NGAP_WARN("Received NG Error indication cause transport case not handled\n"); + } + + break; + + case NGAP_Cause_PR_nas: + switch (ie->value.choice.Cause.choice.nas) { + case NGAP_CauseNas_normal_release: + NGAP_WARN("Received NG Error indication NGAP_CauseNas_normal_release\n"); + break; + + case NGAP_CauseNas_authentication_failure: + NGAP_WARN("Received NG Error indication NGAP_CauseNas_authentication_failure\n"); + break; + + case NGAP_CauseNas_deregister: + NGAP_WARN("Received NG Error indication NGAP_CauseNas_deregister\n"); + break; + + case NGAP_CauseNas_unspecified: + NGAP_WARN("Received NG Error indication NGAP_CauseNas_unspecified\n"); + break; + + default: + NGAP_WARN("Received NG Error indication cause nas case not handled\n"); + } + + break; + + case NGAP_Cause_PR_protocol: + switch (ie->value.choice.Cause.choice.protocol) { + case NGAP_CauseProtocol_transfer_syntax_error: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_transfer_syntax_error\n"); + break; + + case NGAP_CauseProtocol_abstract_syntax_error_reject: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_abstract_syntax_error_reject\n"); + break; + + case NGAP_CauseProtocol_abstract_syntax_error_ignore_and_notify: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_abstract_syntax_error_ignore_and_notify\n"); + break; + + case NGAP_CauseProtocol_message_not_compatible_with_receiver_state: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_message_not_compatible_with_receiver_state\n"); + break; + + case NGAP_CauseProtocol_semantic_error: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_semantic_error\n"); + break; + + case NGAP_CauseProtocol_abstract_syntax_error_falsely_constructed_message: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_abstract_syntax_error_falsely_constructed_message\n"); + break; + + case NGAP_CauseProtocol_unspecified: + NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_unspecified\n"); + break; + + default: + NGAP_WARN("Received NG Error indication cause protocol case not handled\n"); + } + + break; + + case NGAP_Cause_PR_misc: + switch (ie->value.choice.Cause.choice.protocol) { + case NGAP_CauseMisc_control_processing_overload: + NGAP_WARN("Received NG Error indication NGAP_CauseMisc_control_processing_overload\n"); + break; + + case NGAP_CauseMisc_not_enough_user_plane_processing_resources: + NGAP_WARN("Received NG Error indication NGAP_CauseMisc_not_enough_user_plane_processing_resources\n"); + break; + + case NGAP_CauseMisc_hardware_failure: + NGAP_WARN("Received NG Error indication NGAP_CauseMisc_hardware_failure\n"); + break; + + case NGAP_CauseMisc_om_intervention: + NGAP_WARN("Received NG Error indication NGAP_CauseMisc_om_intervention\n"); + break; + + case NGAP_CauseMisc_unspecified: + NGAP_WARN("Received NG Error indication NGAP_CauseMisc_unspecified\n"); + break; + + case NGAP_CauseMisc_unknown_PLMN: + NGAP_WARN("Received NG Error indication NGAP_CauseMisc_unknown_PLMN\n"); + break; + + default: + NGAP_WARN("Received NG Error indication cause misc case not handled\n"); + } + + break; + + default: + NGAP_WARN("Received NG Error indication cause NGAP_Cause_PR_choice_Extensions\n"); + break; + + } + } + + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_CriticalityDiagnostics, false); + + if (ie) { + // TODO continue + } + + + // TODO continue + return 0; +} + + +static +int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + int i; + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + MessageDef *message_p = NULL; + NGAP_InitialContextSetupRequest_t *container; + NGAP_InitialContextSetupRequestIEs_t *ie; + NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id; + uint64_t amf_ue_ngap_id; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.InitialContextSetupRequest; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received initial context setup request for non " + "existing AMF context\n", assoc_id); + return -1; + } + + /* id-AMF-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + } else { + return -1; + } + + /* id-RAN-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + + if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, + ran_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received initial context setup request for non " + "existing UE context 0x%06lx\n", assoc_id, + ran_ue_ngap_id); + return -1; + } + } else { + return -1; + } + + /* Initial context request = UE-related procedure -> stream != 0 */ + //if (stream == 0) { + // NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n", + // assoc_id, stream); + // return -1; + //} + + ue_desc_p->rx_stream = stream; + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; + + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_INITIAL_CONTEXT_SETUP_REQ); + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; + ue_desc_p->ue_initial_id = 0; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; + /* id-UEAggregateMaximumBitRate */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate, false); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateUL), + &(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul)); + asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateDL), + &(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); + } else { + NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate\n"); + } + + + /* id-GUAMI */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_GUAMI, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + TBCD_TO_MCC_MNC(&ie->value.choice.GUAMI.pLMNIdentity, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mcc, + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mnc, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mnc_len); + + OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFRegionID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_region_id); + OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.aMFSetID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_set_id); + OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFPointer, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_pointer); + } else {/* ie != NULL */ + return -1; + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq, false); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_pdusessions = + ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; + + for (i = 0; i < ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; i++) { + NGAP_PDUSessionResourceSetupItemCxtReq_t *item_p; + asn_dec_rval_t dec_rval; + NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL; + NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; + + item_p = (NGAP_PDUSessionResourceSetupItemCxtReq_t *)ie->value.choice.PDUSessionResourceSetupListCxtReq.list.array[i]; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].pdusession_id = item_p->pDUSessionID; + + if (item_p->nAS_PDU != NULL) { + /* Only copy NAS pdu if present */ + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.length = item_p->nAS_PDU->size; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer = + malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); + memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer, + item_p->nAS_PDU->buf, item_p->nAS_PDU->size); + NGAP_DEBUG("Received NAS message with the PDUSESSION setup procedure\n"); + } else { + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.length = 0; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer = NULL; + } + + + dec_rval = aper_decode(NULL, + &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, + (void **)&pdusessionTransfer_p, + item_p->pDUSessionResourceSetupRequestTransfer.buf, + item_p->pDUSessionResourceSetupRequestTransfer.size, 0, 0); + + if(dec_rval.code != RC_OK) { + NGAP_ERROR("could not decode PDUSessionResourceSetupRequestTransfer\n"); + return -1; + } + + for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) { + pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j]; + switch(pdusessionTransfer_ies->id) { + /* optional PDUSessionAggregateMaximumBitRate */ + case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: + break; + + /* mandatory UL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation: + { + NGAP_GTPTunnel_t *gTPTunnel_p; + gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; + + /* Set the transport layer address */ + memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.buffer, + gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); + + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.length = + gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; + + /* GTP tunnel endpoint ID */ + OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].gtp_teid); + } + + break; + + /* optional AdditionalUL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: + break; + + /* optional DataForwardingNotPossible */ + case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible: + break; + + /* mandatory PDUSessionType */ + case NGAP_ProtocolIE_ID_id_PDUSessionType: + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + break; + + /* optional SecurityIndication */ + case NGAP_ProtocolIE_ID_id_SecurityIndication: + break; + + /* optional NetworkInstance */ + case NGAP_ProtocolIE_ID_id_NetworkInstance: + break; + + /* mandatory QosFlowSetupRequestList */ + case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList: + { + NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p; + + NGAP_DEBUG("QosFlowSetupRequestList.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count); + DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0); + DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows); + + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; + + for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++) { + qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx]; + + /* Set the QOS informations */ + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level = + qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = + qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = + qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability; + } + } + + break; + + /* optional CommonNetworkInstance */ + case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: + break; + + default: + NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); + return -1; + } + } + + } /* for i... */ + } else {/* ie != NULL */ + NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n"); + } + + /* id-AllowedNSSAI */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AllowedNSSAI, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_AllowedNSSAI_Item_t *allow_nssai_item_p = NULL; + + NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count); + DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0); + DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs); + + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count; + + for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) { + allow_nssai_item_p = ie->value.choice.AllowedNSSAI.list.array[i]; + + OCTET_STRING_TO_INT8(&allow_nssai_item_p->s_NSSAI.sST, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sST); + + if(allow_nssai_item_p->s_NSSAI.sD != NULL) { + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD_flag = 1; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[0] = allow_nssai_item_p->s_NSSAI.sD->buf[0]; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[1] = allow_nssai_item_p->s_NSSAI.sD->buf[1]; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2]; + } + } + } else {/* ie != NULL */ + return -1; + } + + /* id-UESecurityCapabilities */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_UESecurityCapabilities, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.nRencryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRencryptionAlgorithms); + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.nRintegrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRintegrityProtectionAlgorithms); + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.eUTRAencryption_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAencryptionAlgorithms); + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.eUTRAintegrity_algorithms = + BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAintegrityProtectionAlgorithms); + /* id-SecurityKey : Copy the security key */ + } else {/* ie != NULL */ + return -1; + } + + /* id-MobilityRestrictionList */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_SecurityKey, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + memcpy(&NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, + ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); + + } else {/* ie != NULL */ + return -1; + } + + /* id-NAS-PDU */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_MobilityRestrictionList, false); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_MobilityRestrictionList_t *mobility_rest_list_p = NULL; + mobility_rest_list_p = &ie->value.choice.MobilityRestrictionList; + + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction_flag = 1; + TBCD_TO_MCC_MNC(&mobility_rest_list_p->servingPLMN, + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mcc, + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mnc, + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mnc_digit_length); + } + + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_NAS_PDU, false); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + if(ie->value.choice.NAS_PDU.size > 0) { + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu_flag = 1; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size; + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); + memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.buffer, + ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); + } + + } + + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + + return 0; +} + + +static +int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + MessageDef *message_p = NULL; + uint64_t amf_ue_ngap_id; + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + NGAP_UEContextReleaseCommand_t *container; + NGAP_UEContextReleaseCommand_IEs_t *ie; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received UE context release command for non " + "existing AMF context\n", assoc_id); + return -1; + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_UEContextReleaseCommand_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_UE_NGAP_IDs, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + switch (ie->value.choice.UE_NGAP_IDs.present) { + case NGAP_UE_NGAP_IDs_PR_uE_NGAP_ID_pair: + gnb_ue_ngap_id = ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->rAN_UE_NGAP_ID; + asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->aMF_UE_NGAP_ID), &amf_ue_ngap_id); + MSC_LOG_RX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + NULL,0, + "0 UEContextRelease/%s gNB_ue_ngap_id "NGAP_UE_ID_FMT" amf_ue_ngap_id "NGAP_UE_ID_FMT" len %u", + ngap_direction2String(pdu->present - 1), + gnb_ue_ngap_id, + amf_ue_ngap_id); + + if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, + gnb_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received UE context release command for non " + "existing UE context 0x%06lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } else { + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_RRC_GNB, + NULL,0, + "0 NGAP_UE_CONTEXT_RELEASE_COMMAND/%d gNB_ue_ngap_id "NGAP_UE_ID_FMT" ", + gnb_ue_ngap_id); + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); + + if (ue_desc_p->amf_ue_ngap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; + } + + NGAP_UE_CONTEXT_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + return 0; + } + + break; + + //#warning "TODO mapping amf_ue_ngap_id gnb_ue_ngap_id?" + + case NGAP_UE_NGAP_IDs_PR_aMF_UE_NGAP_ID: + asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.aMF_UE_NGAP_ID), &amf_ue_ngap_id); + NGAP_ERROR("TO DO mapping amf_ue_ngap_id gnb_ue_ngap_id"); + (void)amf_ue_ngap_id; /* TODO: remove - it's to remove gcc warning about unused var */ + + case NGAP_UE_NGAP_IDs_PR_NOTHING: + default: + NGAP_ERROR("NGAP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements"); + return -1; + } + } else { + return -1; + } + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_UEContextReleaseCommand_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_Cause, true); + /* TBD */ + + return 0; +} + +static +int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { +// NGAP_AMF_UE_NGAP_ID_t amf_ue_ngap_id; + uint64_t amf_ue_ngap_id; + NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id; + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + MessageDef *message_p = NULL; + NGAP_PDUSessionResourceSetupRequest_t *container; + NGAP_PDUSessionResourceSetupRequestIEs_t *ie; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceSetupRequest; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received pdu session resource setup request for non " + "existing AMF context\n", assoc_id); + return -1; + } + + /* id-AMF-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + } else { + return -1; + } + + /* id-gNB-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + } else { + return -1; + } + + if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, + ran_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received pdu session resource setup request for non " + "existing UE context 0x%06lx\n", assoc_id, + ran_ue_ngap_id); + return -1; + } + + /* Initial context request = UE-related procedure -> stream != 0 */ + // if (stream == 0) { + // NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n", + // assoc_id, stream); + // return -1; + // } + + ue_desc_p->rx_stream = stream; + + if ( ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%lu != %lu)", + (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id); + } + + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_SETUP_REQ); + NGAP_PDUSESSION_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; + ue_desc_p->ue_initial_id = 0; + NGAP_PDUSESSION_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id; + NGAP_PDUSESSION_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id; + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_PDUSESSION_SETUP_REQ(message_p).nb_pdusessions_tosetup = + ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; + + for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) { + NGAP_PDUSessionResourceSetupItemSUReq_t *item_p; + asn_dec_rval_t dec_rval; + NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL; + NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL; + + item_p = (NGAP_PDUSessionResourceSetupItemSUReq_t *)ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i]; + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; + + + // check for the NAS PDU + if (item_p->pDUSessionNAS_PDU->size > 0 ) { + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length = item_p->pDUSessionNAS_PDU->size; + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionNAS_PDU->size); + memcpy(NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer, + item_p->pDUSessionNAS_PDU->buf, item_p->pDUSessionNAS_PDU->size); + // NGAP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); + } else { + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length = 0; + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer = NULL; + NGAP_WARN("NAS PDU is not provided, generate a PDUSESSION_SETUP Failure (TBD) back to AMF \n"); + } + + dec_rval = aper_decode(NULL, + &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, + (void **)&pdusessionTransfer_p, + item_p->pDUSessionResourceSetupRequestTransfer.buf, + item_p->pDUSessionResourceSetupRequestTransfer.size, 0, 0); + + if(dec_rval.code != RC_OK) { + NGAP_ERROR("could not decode PDUSessionResourceSetupRequestTransfer\n"); + return -1; + } + + for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) { + pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j]; + + switch(pdusessionTransfer_ies->id) { + /* optional PDUSessionAggregateMaximumBitRate */ + case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: + break; + + /* mandatory UL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation: + { + NGAP_GTPTunnel_t *gTPTunnel_p; + gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel; + /* The transport layer address for the IP packets */ + OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].gtp_teid); + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.length = + gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused; + memcpy(NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.buffer , + gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); + } + break; + + /* optional AdditionalUL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: + break; + + /* optional DataForwardingNotPossible */ + case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible: + break; + + /* mandatory PDUSessionType */ + case NGAP_ProtocolIE_ID_id_PDUSessionType: + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; + break; + + /* optional SecurityIndication */ + case NGAP_ProtocolIE_ID_id_SecurityIndication: + break; + + /* optional NetworkInstance */ + case NGAP_ProtocolIE_ID_id_NetworkInstance: + break; + + /* mandatory QosFlowSetupRequestList */ + case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList: + { + NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p; + + NGAP_DEBUG("servedGUAMIs.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count); + DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0); + DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows); + + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; + + for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++){ + qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx]; + + /* Set the QOS informations */ + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ + if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI = + (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; + } + } + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level = + qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = + qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability; + NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = + qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability; + } + } + break; + + /* optional CommonNetworkInstance */ + case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: + break; + + default: + NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); + return -1; + } + }/* for j... */ + } /* for i... */ + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + }else {/* ie == NULL */ + NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq\n"); + return -1; + } + return 0; +} + + +static +int ngap_gNB_handle_paging(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + MessageDef *message_p = NULL; + NGAP_Paging_t *container; + NGAP_PagingIEs_t *ie; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.Paging; + // received Paging Message from AMF + NGAP_DEBUG("[SCTP %d] Received Paging Message From AMF\n",assoc_id); + + /* Paging procedure -> stream != 0 */ + if (stream == 0) { + LOG_W(NGAP,"[SCTP %d] Received Paging procedure on stream (%d)\n", + assoc_id, stream); + return -1; + } + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received Paging for non " + "existing AMF context\n", assoc_id); + return -1; + } + + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + + if (ngap_gNB_instance == NULL) { + NGAP_ERROR("[SCTP %d] Received Paging for non existing AMF context : ngap_gNB_instance is NULL\n", + assoc_id); + return -1; + } + + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PAGING_IND); + /* convert NGAP_PagingIEs_t to ngap_paging_ind_t */ + /* id-UEIdentityIndexValue : convert UE Identity Index value */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_UEPagingIdentity, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + OCTET_STRING_TO_INT16(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFSetID, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id); + OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFPointer, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer); + OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->fiveG_TMSI, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi); + + NGAP_DEBUG("[SCTP %d] Received Paging Identity amf_set_id %d, amf_pointer %d, m_tmsi %d\n", + assoc_id, + NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id, + NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer, + NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi); + } else { + return -1; + } + + + NGAP_PAGING_IND(message_p).paging_drx = NGAP_PAGING_DRX_256; + /* id-pagingDRX */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PagingDRX, false); + + /* optional */ + if (ie) { + NGAP_PAGING_IND(message_p).paging_drx = ie->value.choice.PagingDRX; + } else { + NGAP_PAGING_IND(message_p).paging_drx = NGAP_PAGING_DRX_256; + } + + memset (&NGAP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256); + memset (&NGAP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256); + NGAP_PAGING_IND(message_p).tai_size = 0; + /* id-TAIList */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_TAIListForPaging, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_INFO("[SCTP %d] Received Paging taiList For Paging: count %d\n", assoc_id, ie->value.choice.TAIListForPaging.list.count); + + for (int i = 0; i < ie->value.choice.TAIListForPaging.list.count; i++) { + NGAP_TAIListForPagingItem_t *item_p; + item_p = (NGAP_TAIListForPagingItem_t *)ie->value.choice.TAIListForPaging.list.array[i]; + TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNIdentity), NGAP_PAGING_IND(message_p).plmn_identity[i].mcc, + NGAP_PAGING_IND(message_p).plmn_identity[i].mnc, + NGAP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length); + OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), NGAP_PAGING_IND(message_p).tac[i]); + NGAP_PAGING_IND(message_p).tai_size++; + NGAP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, + NGAP_PAGING_IND(message_p).plmn_identity[i].mcc, + NGAP_PAGING_IND(message_p).plmn_identity[i].mnc, + NGAP_PAGING_IND(message_p).tac[i]); + } + } else { + return -1; + } + + //paging parameter values + NGAP_DEBUG("[SCTP %d] Received Paging parameters: Paging Identity amf_set_id %d amf_pointer %d m_tmsi %d paging_drx %d paging_priority %d\n",assoc_id, + NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id, + NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer, + NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi, + NGAP_PAGING_IND(message_p).paging_drx, NGAP_PAGING_IND(message_p).paging_priority); + /* send message to RRC */ + itti_send_msg_to_task(TASK_RRC_GNB, ngap_gNB_instance->instance, message_p); + + return 0; +} + +static +int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + int i, nb_of_pdusessions_failed; + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + MessageDef *message_p = NULL; + NGAP_PDUSessionResourceModifyRequest_t *container; + NGAP_PDUSessionResourceModifyRequestIEs_t *ie; + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + uint64_t amf_ue_ngap_id; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceModifyRequest; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received PDUSession Resource modify request for non " + "existing AMF context\n", assoc_id); + return -1; + } + + /* id-AMF-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + } else { + return -1; + } + + /* id-RAN-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + } else { + return -1; + } + + if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, + gnb_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received PDUSession Resource modify request for non " + "existing UE context 0x%08lx\n", assoc_id, + gnb_ue_ngap_id); + return -1; + } + + /* PDUSession Resource modify request = UE-related procedure -> stream != 0 */ + if (stream == 0) { + NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n", + assoc_id, stream); + return -1; + } + + ue_desc_p->rx_stream = stream; + + if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%ld != %ld)", + (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id); + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP); + NGAP_PDUSESSION_MODIFY_RESP (message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + for(nb_of_pdusessions_failed = 0; nb_of_pdusessions_failed < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; nb_of_pdusessions_failed++) { + NGAP_PDUSessionResourceModifyItemModReq_t *item_p; + item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[nb_of_pdusessions_failed]; + + NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].pdusession_id = item_p->pDUSessionID; + NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].cause = NGAP_Cause_PR_radioNetwork; + NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID; + } + } else { + return -1; + } + + NGAP_PDUSESSION_MODIFY_RESP(message_p).nb_of_pdusessions_failed = nb_of_pdusessions_failed; + ngap_gNB_pdusession_modify_resp(amf_desc_p->ngap_gNB_instance->instance, + &NGAP_PDUSESSION_MODIFY_RESP(message_p)); + itti_free(TASK_RRC_GNB,message_p); + message_p = NULL; + return -1; + } + + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_MODIFY_REQ); + NGAP_PDUSESSION_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; + NGAP_PDUSESSION_MODIFY_REQ(message_p).amf_ue_ngap_id = amf_ue_ngap_id; + NGAP_PDUSESSION_MODIFY_REQ(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + /* id-PDUSessionResourceModifyListModReq */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_PDUSESSION_MODIFY_REQ(message_p).nb_pdusessions_tomodify = + ie->value.choice.PDUSessionResourceModifyListModReq.list.count; + + for (i = 0; i < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; i++) { + NGAP_PDUSessionResourceModifyItemModReq_t *item_p; + asn_dec_rval_t dec_rval; + NGAP_PDUSessionResourceModifyRequestTransfer_t *pdusessionTransfer_p = NULL; + NGAP_PDUSessionResourceModifyRequestTransferIEs_t *pdusessionTransfer_ies = NULL; + + item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[i]; + + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].pdusession_id = item_p->pDUSessionID; + + // check for the NAS PDU + if (item_p->nAS_PDU != NULL && item_p->nAS_PDU->size > 0 ) { + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.length = item_p->nAS_PDU->size; + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); + memcpy(NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer, + item_p->nAS_PDU->buf, item_p->nAS_PDU->size); + } else { + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.length = 0; + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer = NULL; + continue; + } + + dec_rval = aper_decode(NULL, + &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, + (void **)&pdusessionTransfer_p, + item_p->pDUSessionResourceModifyRequestTransfer.buf, + item_p->pDUSessionResourceModifyRequestTransfer.size, 0, 0); + + if(dec_rval.code != RC_OK) { + NGAP_ERROR("could not decode PDUSessionResourceModifyRequestTransfer\n"); + return -1; + } + + for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) { + pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j]; + switch(pdusessionTransfer_ies->id) { + /* optional PDUSessionAggregateMaximumBitRate */ + case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate: + break; + + /* optional UL-NGU-UP-TNLModifyList */ + case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList: + break; + + /* optional NetworkInstance */ + case NGAP_ProtocolIE_ID_id_NetworkInstance: + break; + + /* optional QosFlowAddOrModifyRequestList */ + case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList: + { + NGAP_QosFlowAddOrModifyRequestItem_t *qosFlowItem_p; + + NGAP_DEBUG("QosFlowAddOrModifyRequestList.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count); + DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count > 0); + DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count <= NGAP_maxnoofQosFlows); + + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; + + for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; qosIdx++) { + qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.array[qosIdx]; + + /* Set the QOS informations */ + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + if(qosFlowItem_p->qosFlowLevelQosParameters) { + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.priority_level = + qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.priorityLevelARP; + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability = + qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionCapability; + NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability = + qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionVulnerability; + } + } + } + break; + + /* optional QosFlowToReleaseList */ + case NGAP_ProtocolIE_ID_id_QosFlowToReleaseList: + break; + + /* optional AdditionalUL-NGU-UP-TNLInformation */ + case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation: + break; + + /* optional CommonNetworkInstance */ + case NGAP_ProtocolIE_ID_id_CommonNetworkInstance: + break; + + default: + NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id); + return -1; + } + } + } + + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + } else { /* of if (ie != NULL)*/ + return -1; + } + + return 0; +} +// handle pdu session release command and send it to rrc_end +static +int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + int i; + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + MessageDef *message_p = NULL; + NGAP_PDUSessionResourceReleaseCommand_t *container; + NGAP_PDUSessionResourceReleaseCommandIEs_t *ie; + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + uint64_t amf_ue_ngap_id; + DevAssert(pdu != NULL); + container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceReleaseCommand; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received pdu session release command for non existing AMF context\n", assoc_id); + return -1; + } + + + /* id-AMF-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + } else { + return -1; + } + + /* id-RAN-UE-NGAP-ID */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + } else { + return -1; + } + + if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance, + gnb_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received PDUSession Resource release command for non existing UE context 0x%08lx\n", assoc_id, + ie->value.choice.RAN_UE_NGAP_ID); + return -1; + } + + /* Initial context request = UE-related procedure -> stream != 0 */ + // if (stream == 0) { + // NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n", + // assoc_id, stream); + // return -1; + // } + + ue_desc_p->rx_stream = stream; + + if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%lu != %lu)", + (uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id); + } + + NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n", + assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id); + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND); + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id; + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).amf_ue_ngap_id = amf_ue_ngap_id; + /* id-NAS-PDU */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_NAS_PDU, false); + + if(ie && ie->value.choice.NAS_PDU.size > 0) { + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size; + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size); + memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer, + ie->value.choice.NAS_PDU.buf, + ie->value.choice.NAS_PDU.size); + } else { + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.length = 0; + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL; + } + + /* id-PDUSessionResourceToReleaseListRelCmd */ + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container, + NGAP_ProtocolIE_ID_id_PDUSessionResourceToReleaseListRelCmd, true); + + if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nb_pdusessions_torelease = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; + + for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) { + NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p; + item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i]; + + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID; + if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) { + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size; + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size); + memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer, + item_p->pDUSessionResourceReleaseCommandTransfer.buf, + item_p->pDUSessionResourceReleaseCommandTransfer.size); + }else { + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = 0; + NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = NULL; + NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n"); + } + NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID); + } + } else { + return -1; + } + + itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + + return 0; +} + +static +int ngap_gNB_handle_ng_path_switch_request_ack(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + // TODO + return 0; +} + +static +int ngap_gNB_handle_ng_path_switch_request_failure(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) { + + // TODO + return 0; +} + +static +int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu){ + + LOG_W(NGAP, "Implementation of NGAP Pdusession Modification confirm handler is pending...\n"); + return 0; +} + diff --git a/common/utils/itti_analyzer/libparser/enum_value_type.h b/openair3/NGAP/ngap_gNB_handlers.h similarity index 63% rename from common/utils/itti_analyzer/libparser/enum_value_type.h rename to openair3/NGAP/ngap_gNB_handlers.h index 997e6cc3fe..889946dd44 100644 --- a/common/utils/itti_analyzer/libparser/enum_value_type.h +++ b/openair3/NGAP/ngap_gNB_handlers.h @@ -18,20 +18,21 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ + +/*! \file ngap_gNB_handlers.h + * \brief ngap messages handlers for gNB part + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +#ifndef NGAP_GNB_HANDLERS_H_ +#define NGAP_GNB_HANDLERS_H_ -#include "types.h" +void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shutdown); -#ifndef ENUM_VALUE_TYPE_H_ -#define ENUM_VALUE_TYPE_H_ +int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream, + const uint8_t * const data, const uint32_t data_length); -extern uint32_t last_enum_value; - -int enum_value_dissect_from_buffer( - types_t *type, ui_set_signal_text_cb_t ui_set_signal_text_cb, gpointer user_data, - buffer_t *buffer, uint32_t offset, uint32_t parent_offset, int indent, gboolean new_line); - -int enum_value_file_print(types_t *type, int indent, FILE *file); - -int enum_value_type_hr_display(types_t *type, int indent); - -#endif /* ENUM_VALUE_TYPE_H_ */ +#endif /* NGAP_GNB_HANDLERS_H_ */ diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.c b/openair3/NGAP/ngap_gNB_itti_messaging.c new file mode 100644 index 0000000000..ab10fa46e2 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_itti_messaging.c @@ -0,0 +1,85 @@ +/* + * 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 ngap_gNB_itti_messaging.c + * \brief ngap itti messages handlers for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +#include "intertask_interface.h" + +#include "ngap_gNB_itti_messaging.h" + +void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream) +{ + MessageDef *message_p; + sctp_data_req_t *sctp_data_req; + + message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_DATA_REQ); + + sctp_data_req = &message_p->ittiMsg.sctp_data_req; + + sctp_data_req->assoc_id = assoc_id; + sctp_data_req->buffer = buffer; + sctp_data_req->buffer_length = buffer_length; + sctp_data_req->stream = stream; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, + uint16_t ue_initial_id, + uint32_t gNB_ue_ngap_id, + uint8_t *nas_pdu, + uint32_t nas_pdu_length) +{ + MessageDef *message_p; + ngap_downlink_nas_t *ngap_downlink_nas; + + message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DOWNLINK_NAS); + + ngap_downlink_nas = &message_p->ittiMsg.ngap_downlink_nas; + + ngap_downlink_nas->ue_initial_id = ue_initial_id; + ngap_downlink_nas->gNB_ue_ngap_id = gNB_ue_ngap_id; + ngap_downlink_nas->nas_pdu.buffer = malloc(sizeof(uint8_t) * nas_pdu_length); + memcpy(ngap_downlink_nas->nas_pdu.buffer, nas_pdu, nas_pdu_length); + ngap_downlink_nas->nas_pdu.length = nas_pdu_length; + + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); +} + +void ngap_gNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.h b/openair3/NGAP/ngap_gNB_itti_messaging.h new file mode 100644 index 0000000000..94d4058178 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_itti_messaging.h @@ -0,0 +1,46 @@ +/* + * 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 ngap_gNB_itti_messaging.h + * \brief ngap itti messages handlers for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \date 2020 + * \version 0.1 + */ + +#ifndef NGAP_GNB_ITTI_MESSAGING_H_ +#define NGAP_GNB_ITTI_MESSAGING_H_ + +void ngap_gNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer, + uint32_t buffer_length, uint16_t stream); + +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, + uint16_t ue_initial_id, + uint32_t gNB_ue_ngap_id, + uint8_t *nas_pdu, + uint32_t nas_pdu_length); + +void ngap_gNB_itti_send_sctp_close_association(instance_t instance, + int32_t assoc_id); + + +#endif /* NGAP_GNB_ITTI_MESSAGING_H_ */ diff --git a/openair3/NGAP/ngap_gNB_management_procedures.c b/openair3/NGAP/ngap_gNB_management_procedures.c new file mode 100644 index 0000000000..85167ed7f0 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_management_procedures.c @@ -0,0 +1,193 @@ +/* + * 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 ngap_gNB_management_procedures.c + * \brief NGAP gNB task + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + +#include +#include +#include + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" +#include "ngap_gNB.h" + +ngap_gNB_internal_data_t ngap_gNB_internal_data; + +RB_GENERATE(ngap_amf_map, ngap_gNB_amf_data_s, entry, ngap_gNB_compare_assoc_id); + +int ngap_gNB_compare_assoc_id( + struct ngap_gNB_amf_data_s *p1, struct ngap_gNB_amf_data_s *p2) +{ + if (p1->assoc_id == -1) { + if (p1->cnx_id < p2->cnx_id) { + return -1; + } + + if (p1->cnx_id > p2->cnx_id) { + return 1; + } + } else { + if (p1->assoc_id < p2->assoc_id) { + return -1; + } + + if (p1->assoc_id > p2->assoc_id) { + return 1; + } + } + + /* Matching reference */ + return 0; +} + +uint16_t ngap_gNB_fetch_add_global_cnx_id(void) +{ + return ++ngap_gNB_internal_data.global_cnx_id; +} + +void ngap_gNB_prepare_internal_data(void) +{ + memset(&ngap_gNB_internal_data, 0, sizeof(ngap_gNB_internal_data)); + STAILQ_INIT(&ngap_gNB_internal_data.ngap_gNB_instances_head); +} + +void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p) +{ + DevAssert(new_instance_p != NULL); + + STAILQ_INSERT_TAIL(&ngap_gNB_internal_data.ngap_gNB_instances_head, + new_instance_p, ngap_gNB_entries); +} + +struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF( + ngap_gNB_instance_t *instance_p, + int32_t assoc_id, uint16_t cnx_id) +{ + struct ngap_gNB_amf_data_s temp; + struct ngap_gNB_amf_data_s *found; + + memset(&temp, 0, sizeof(struct ngap_gNB_amf_data_s)); + + temp.assoc_id = assoc_id; + temp.cnx_id = cnx_id; + + if (instance_p == NULL) { + STAILQ_FOREACH(instance_p, &ngap_gNB_internal_data.ngap_gNB_instances_head, + ngap_gNB_entries) { + found = RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp); + + if (found != NULL) { + return found; + } + } + } else { + return RB_FIND(ngap_amf_map, &instance_p->ngap_amf_head, &temp); + } + + return NULL; +} + +struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance( + ngap_gNB_instance_t *instance_p) +{ + + struct ngap_gNB_amf_data_s *amf = NULL; + struct ngap_gNB_amf_data_s *amf_next = NULL; + + for (amf = RB_MIN(ngap_amf_map, &instance_p->ngap_amf_head); amf!=NULL ; amf = amf_next) { + amf_next = RB_NEXT(ngap_amf_map, &instance_p->ngap_amf_head, amf); + if (amf->ngap_gNB_instance == instance_p) { + return amf; + } + } + + return NULL; +} + +ngap_gNB_instance_t *ngap_gNB_get_instance(instance_t instance) +{ + ngap_gNB_instance_t *temp = NULL; + + STAILQ_FOREACH(temp, &ngap_gNB_internal_data.ngap_gNB_instances_head, + ngap_gNB_entries) { + if (temp->instance == instance) { + /* Matching occurence */ + return temp; + } + } + + return NULL; +} + +void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance) +{ + + struct ngap_gNB_amf_data_s *amf = NULL; + struct ngap_gNB_amf_data_s *amfNext = NULL; + struct plmn_identity_s* plmnInfo; + struct served_region_id_s* regionInfo; + struct served_guami_s* guamInfo; + struct amf_set_id_s* amfSet; + struct amf_pointer_s* amfPoint; + for (amf = RB_MIN(ngap_amf_map, &instance->ngap_amf_head); amf; amf = amfNext) { + amfNext = RB_NEXT(ngap_amf_map, &instance->ngap_amf_head, amf); + RB_REMOVE(ngap_amf_map, &instance->ngap_amf_head, amf); + while (!STAILQ_EMPTY(&amf->served_guami)) { + guamInfo = STAILQ_FIRST(&amf->served_guami); + STAILQ_REMOVE_HEAD(&amf->served_guami, next); + + while (!STAILQ_EMPTY(&guamInfo->served_plmns)) { + plmnInfo = STAILQ_FIRST(&guamInfo->served_plmns); + STAILQ_REMOVE_HEAD(&guamInfo->served_plmns, next); + free(plmnInfo); + } + while (!STAILQ_EMPTY(&guamInfo->served_region_ids)) { + regionInfo = STAILQ_FIRST(&guamInfo->served_region_ids); + STAILQ_REMOVE_HEAD(&guamInfo->served_region_ids, next); + free(regionInfo); + } + while (!STAILQ_EMPTY(&guamInfo->amf_set_ids)) { + amfSet = STAILQ_FIRST(&guamInfo->amf_set_ids); + STAILQ_REMOVE_HEAD(&guamInfo->amf_set_ids, next); + free(amfSet); + } + while (!STAILQ_EMPTY(&guamInfo->amf_pointers)) { + amfPoint = STAILQ_FIRST(&guamInfo->amf_pointers); + STAILQ_REMOVE_HEAD(&guamInfo->amf_pointers, next); + free(amfPoint); + } + free(guamInfo); + } + free(amf); + } +} diff --git a/common/utils/itti_analyzer/libbuffers/socket.h b/openair3/NGAP/ngap_gNB_management_procedures.h similarity index 53% rename from common/utils/itti_analyzer/libbuffers/socket.h rename to openair3/NGAP/ngap_gNB_management_procedures.h index 8c2be2243e..e192f71be9 100644 --- a/common/utils/itti_analyzer/libbuffers/socket.h +++ b/openair3/NGAP/ngap_gNB_management_procedures.h @@ -19,34 +19,32 @@ * contact@openairinterface.org */ -#include -#include +/*! \file ngap_gNB_management_procedures.h + * \brief NGAP gNB task + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ -#ifndef SOCKET_H_ -#define SOCKET_H_ +#ifndef NGAP_GNB_MANAGEMENT_PROCEDURES_H_ +#define NGAP_GNB_MANAGEMENT_PROCEDURES_H_ -typedef struct { - pthread_t thread; - int sd; - char *ip_address; - uint16_t port; +struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF( + ngap_gNB_instance_t *instance_p, + int32_t assoc_id, uint16_t cnx_id); - /* The pipe used between main thread (running GTK) and the socket thread */ - int pipe_fd; +struct ngap_gNB_amf_data_s *ngap_gNB_get_AMF_from_instance(ngap_gNB_instance_t *instance_p); - /* Time used to avoid refreshing UI every time a new signal is incoming */ - gint64 last_data_notification; - uint8_t nb_signals_since_last_update; +void ngap_gNB_remove_amf_desc(ngap_gNB_instance_t * instance); - /* The last signals received which are not yet been updated in GUI */ - GList *signal_list; -} socket_data_t; +void ngap_gNB_insert_new_instance(ngap_gNB_instance_t *new_instance_p); -gboolean socket_abort_connection; +ngap_gNB_instance_t *ngap_gNB_get_instance(uint8_t mod_id); -int socket_connect_to_remote_host(const char *remote_ip, const uint16_t port, - int pipe_fd); +uint16_t ngap_gNB_fetch_add_global_cnx_id(void); -int socket_disconnect_from_remote_host(void); +void ngap_gNB_prepare_internal_data(void); -#endif /* SOCKET_H_ */ +#endif /* NGAP_GNB_MANAGEMENT_PROCEDURES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c new file mode 100644 index 0000000000..3711072682 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -0,0 +1,1503 @@ +/* + * 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 ngap_gNB_nas_procedures.c + * \brief NGAP gNb NAS procedure handler + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" + +#include "ngap_gNB_itti_messaging.h" + +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_nnsf.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_nas_procedures.h" +#include "ngap_gNB_management_procedures.h" +#include "msc.h" + +//------------------------------------------------------------------------------ +int ngap_gNB_handle_nas_first_req( + instance_t instance, ngap_nas_first_req_t *ngap_nas_first_req_p) +//------------------------------------------------------------------------------ +{ + ngap_gNB_instance_t *instance_p = NULL; + struct ngap_gNB_amf_data_s *amf_desc_p = NULL; + struct ngap_gNB_ue_context_s *ue_desc_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_InitialUEMessage_t *out; + NGAP_InitialUEMessage_IEs_t *ie; + NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; + uint8_t *buffer = NULL; + uint32_t length = 0; + DevAssert(ngap_nas_first_req_p != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + instance_p = ngap_gNB_get_instance(instance); + DevAssert(instance_p != NULL); + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_InitialUEMessage; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_InitialUEMessage; + out = &pdu.choice.initiatingMessage->value.choice.InitialUEMessage; + + /* Select the AMF corresponding to the provided GUAMI. */ + //TODO have not be test. it's should be test + if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_guami) { + amf_desc_p = ngap_gNB_nnsf_select_amf_by_guami( + instance_p, + ngap_nas_first_req_p->establishment_cause, + ngap_nas_first_req_p->ue_identity.guami); + + if (amf_desc_p) { + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through GUAMI MCC %d MNC %d AMFRI %d AMFSI %d AMFPT %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + ngap_nas_first_req_p->ue_identity.guami.mcc, + ngap_nas_first_req_p->ue_identity.guami.mnc, + ngap_nas_first_req_p->ue_identity.guami.amf_region_id, + ngap_nas_first_req_p->ue_identity.guami.amf_set_id, + ngap_nas_first_req_p->ue_identity.guami.amf_pointer); + } + } + + if (amf_desc_p == NULL) { + /* Select the AMF corresponding to the provided s-TMSI. */ + //TODO have not be test. it's should be test + if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { + amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid( + instance_p, + ngap_nas_first_req_p->establishment_cause, + ngap_nas_first_req_p->selected_plmn_identity, + ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id); + + if (amf_desc_p) { + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, + ngap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); + } + } + } + + if (amf_desc_p == NULL) { + /* Select AMF based on the selected PLMN identity, received through RRC + * Connection Setup Complete */ + //TODO have not be test. it's should be test + amf_desc_p = ngap_gNB_nnsf_select_amf_by_plmn_id( + instance_p, + ngap_nas_first_req_p->establishment_cause, + ngap_nas_first_req_p->selected_plmn_identity); + + if (amf_desc_p) { + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + ngap_nas_first_req_p->selected_plmn_identity, + instance_p->mcc[ngap_nas_first_req_p->selected_plmn_identity], + instance_p->mnc[ngap_nas_first_req_p->selected_plmn_identity]); + } + } + + if (amf_desc_p == NULL) { + /* + * If no AMF corresponds to the GUAMI, the s-TMSI, or the selected PLMN + * identity, selects the AMF with the highest capacity. + */ + //TODO have not be test. it's should be test + amf_desc_p = ngap_gNB_nnsf_select_amf( + instance_p, + ngap_nas_first_req_p->establishment_cause); + + if (amf_desc_p) { + NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through highest relative capacity\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id); + } + } + + if (amf_desc_p == NULL) { + /* + * In case gNB has no AMF associated, the gNB should inform RRC and discard + * this request. + */ + NGAP_WARN("No AMF is associated to the gNB\n"); + // TODO: Inform RRC + return -1; + } + + /* The gNB should allocate a unique gNB UE NGAP ID for this UE. The value + * will be used for the duration of the connectivity. + */ + ue_desc_p = ngap_gNB_allocate_new_UE_context(); + DevAssert(ue_desc_p != NULL); + /* Keep a reference to the selected AMF */ + ue_desc_p->amf_ref = amf_desc_p; + ue_desc_p->ue_initial_id = ngap_nas_first_req_p->ue_initial_id; + ue_desc_p->gNB_instance = instance_p; + ue_desc_p->selected_plmn_identity = ngap_nas_first_req_p->selected_plmn_identity; + + do { + struct ngap_gNB_ue_context_s *collision_p; + /* Peek a random value for the gNB_ue_ngap_id */ + ue_desc_p->gNB_ue_ngap_id = (random() + random()) & 0xffffffff; + + if ((collision_p = RB_INSERT(ngap_ue_map, &instance_p->ngap_ue_head, ue_desc_p)) + == NULL) { + NGAP_DEBUG("Found usable gNB_ue_ngap_id: 0x%08x %u(10)\n", + ue_desc_p->gNB_ue_ngap_id, + ue_desc_p->gNB_ue_ngap_id); + /* Break the loop as the id is not already used by another UE */ + break; + } + } while(1); + + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_desc_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_NAS_PDU; +#if 1 + ie->value.choice.NAS_PDU.buf = ngap_nas_first_req_p->nas_pdu.buffer; +#else + ie->value.choice.NAS_PDU.buf = malloc(ngap_nas_first_req_p->nas_pdu.length); + memcpy(ie->value.choice.NAS_PDU.buf, + ngap_nas_first_req_p->nas_pdu.buffer, + ngap_nas_first_req_p->nas_pdu.length); +#endif + ie->value.choice.NAS_PDU.size = ngap_nas_first_req_p->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UserLocationInformation; + + ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; + + ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = + CALLOC(1, sizeof(*ie->value.choice.UserLocationInformation.choice.userLocationInformationNR)); + userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; + + /* Set nRCellIdentity. default userLocationInformationNR */ + MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, + 0, // Cell ID + &userinfo_nr_p->nR_CGI.nRCellIdentity); + MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + &userinfo_nr_p->nR_CGI.pLMNIdentity); + + /* Set TAI */ + INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); + MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], + instance_p->mnc[ue_desc_p->selected_plmn_identity], + instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + &userinfo_nr_p->tAI.pLMNIdentity); + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + /* Set the establishment cause according to those provided by RRC */ + DevCheck(ngap_nas_first_req_p->establishment_cause < NGAP_RRC_CAUSE_LAST, + ngap_nas_first_req_p->establishment_cause, NGAP_RRC_CAUSE_LAST, 0); + + /* mandatory */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RRCEstablishmentCause; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_RRCEstablishmentCause; + ie->value.choice.RRCEstablishmentCause = ngap_nas_first_req_p->establishment_cause; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (ngap_nas_first_req_p->ue_identity.presenceMask & NGAP_UE_IDENTITIES_FiveG_s_tmsi) { + NGAP_DEBUG("FIVEG_S_TMSI_PRESENT\n"); + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_FiveG_S_TMSI; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_FiveG_S_TMSI; + AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_set_id, + &ie->value.choice.FiveG_S_TMSI.aMFSetID); + AMF_SETID_TO_BIT_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.amf_pointer, + &ie->value.choice.FiveG_S_TMSI.aMFPointer); + M_TMSI_TO_OCTET_STRING(ngap_nas_first_req_p->ue_identity.s_tmsi.m_tmsi, + &ie->value.choice.FiveG_S_TMSI.fiveG_TMSI); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + + /* optional */ + ie = (NGAP_InitialUEMessage_IEs_t *)calloc(1, sizeof(NGAP_InitialUEMessage_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UEContextRequest; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialUEMessage_IEs__value_PR_UEContextRequest; + ie->value.choice.UEContextRequest = NGAP_UEContextRequest_requested; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Failed to encode message */ + DevMessage("Failed to encode initial UE message\n"); + } + + /* Update the current NGAP UE state */ + ue_desc_p->ue_state = NGAP_UE_WAITING_CSR; + /* Assign a stream for this UE : + * From 3GPP 38.412 7)Transport layers: + * Within the SCTP association established between one AMF and gNB pair: + * - a single pair of stream identifiers shall be reserved for the sole use + * of NGAP elementary procedures that utilize non UE-associated signalling. + * - At least one pair of stream identifiers shall be reserved for the sole use + * of NGAP elementary procedures that utilize UE-associated signallings. + * However a few pairs (i.e. more than one) should be reserved. + * - A single UE-associated signalling shall use one SCTP stream and + * the stream should not be changed during the communication of the + * UE-associated signalling. + */ + amf_desc_p->nextstream = (amf_desc_p->nextstream + 1) % amf_desc_p->out_streams; + + if ((amf_desc_p->nextstream == 0) && (amf_desc_p->out_streams > 1)) { + amf_desc_p->nextstream += 1; + } + + ue_desc_p->tx_stream = amf_desc_p->nextstream; + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" initialUEMessage initiatingMessage gNB_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_desc_p->gNB_ue_ngap_id); + /* Send encoded message over sctp */ + ngap_gNB_itti_send_sctp_data_req(instance_p->instance, amf_desc_p->assoc_id, + buffer, length, ue_desc_p->tx_stream); + + return 0; +} + +//------------------------------------------------------------------------------ +int ngap_gNB_handle_nas_downlink(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) +//------------------------------------------------------------------------------ +{ + + ngap_gNB_amf_data_t *amf_desc_p = NULL; + ngap_gNB_ue_context_t *ue_desc_p = NULL; + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + NGAP_DownlinkNASTransport_t *container; + NGAP_DownlinkNASTransport_IEs_t *ie; + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + uint64_t amf_ue_ngap_id; + DevAssert(pdu != NULL); + + /* UE-related procedure -> stream != 0 */ + // if (stream == 0) { + // NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream == 0\n", + // assoc_id); + // return -1; + // } + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR( + "[SCTP %d] Received NAS downlink message for non existing AMF context\n", + assoc_id); + return -1; + } + + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + /* Prepare the NGAP message to encode */ + container = &pdu->choice.initiatingMessage->value.choice.DownlinkNASTransport; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true); + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true); + gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + + if ((ue_desc_p = ngap_gNB_get_ue_context(ngap_gNB_instance, + gnb_ue_ngap_id)) == NULL) { + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + NULL, + 0, + MSC_AS_TIME_FMT" downlinkNASTransport gNB_ue_ngap_id %u amf_ue_ngap_id %u", + gnb_ue_ngap_id, + amf_ue_ngap_id); + NGAP_ERROR("[SCTP %d] Received NAS downlink message for non existing UE context gNB_UE_NGAP_ID: 0x%lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } + + if (0 == ue_desc_p->rx_stream) { + ue_desc_p->rx_stream = stream; + } else if (stream != ue_desc_p->rx_stream) { + NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream %u, expecting %u\n", + assoc_id, stream, ue_desc_p->rx_stream); + return -1; + } + + /* Is it the first outcome of the AMF for this UE ? If so store the amf + * UE ngap id. + */ + if (ue_desc_p->amf_ue_ngap_id == 0) { + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; + } else { + /* We already have a amf ue ngap id check the received is the same */ + if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%"PRIx64"\n", + assoc_id, + amf_ue_ngap_id, + (uint64_t)ue_desc_p->amf_ue_ngap_id + ); + return -1; + } + } + + MSC_LOG_RX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + NULL, + 0, + MSC_AS_TIME_FMT" downlinkNASTransport gNB_ue_ngap_id %u amf_ue_ngap_id %u", + assoc_id, + amf_ue_ngap_id); + + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, + NGAP_ProtocolIE_ID_id_NAS_PDU, true); + /* Forward the NAS PDU to NR-RRC */ + ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, + ue_desc_p->ue_initial_id, + ue_desc_p->gNB_ue_ngap_id, + ie->value.choice.NAS_PDU.buf, + ie->value.choice.NAS_PDU.size); + + return 0; +} + +//------------------------------------------------------------------------------ +int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_p) +//------------------------------------------------------------------------------ +{ + struct ngap_gNB_ue_context_s *ue_context_p; + ngap_gNB_instance_t *ngap_gNB_instance_p; + NGAP_NGAP_PDU_t pdu; + NGAP_UplinkNASTransport_t *out; + NGAP_UplinkNASTransport_IEs_t *ie; + NGAP_UserLocationInformationNR_t *userinfo_nr_p = NULL; + uint8_t *buffer; + uint32_t length; + DevAssert(ngap_uplink_nas_p != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_uplink_nas_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %08x\n", + ngap_uplink_nas_p->gNB_ue_ngap_id); + return -1; + } + + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %u, current state: %d\n", + ngap_uplink_nas_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UplinkNASTransport; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UplinkNASTransport; + out = &pdu.choice.initiatingMessage->value.choice.UplinkNASTransport; + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_AMF_UE_NGAP_ID; + //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = ngap_uplink_nas_p->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = ngap_uplink_nas_p->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(NGAP_UplinkNASTransport_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UserLocationInformation; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_UplinkNASTransport_IEs__value_PR_UserLocationInformation; + + ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; + ie->value.choice.UserLocationInformation.choice.userLocationInformationNR = CALLOC(1,sizeof(struct NGAP_UserLocationInformationNR)); + userinfo_nr_p = ie->value.choice.UserLocationInformation.choice.userLocationInformationNR; + + /* Set nRCellIdentity. default userLocationInformationNR */ + MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, + 0, // Cell ID + &userinfo_nr_p->nR_CGI.nRCellIdentity); + MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + &userinfo_nr_p->nR_CGI.pLMNIdentity); + + /* Set TAI */ + INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); + MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], + ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + &userinfo_nr_p->tAI.pLMNIdentity); + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode uplink NAS transport\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)NULL, + 0, + MSC_AS_TIME_FMT" uplinkNASTransport initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; +} + + +//------------------------------------------------------------------------------ +int ngap_gNB_nas_non_delivery_ind(instance_t instance, + ngap_nas_non_delivery_ind_t *ngap_nas_non_delivery_ind) +//------------------------------------------------------------------------------ +{ + struct ngap_gNB_ue_context_s *ue_context_p; + ngap_gNB_instance_t *ngap_gNB_instance_p; + NGAP_NGAP_PDU_t pdu; + NGAP_NASNonDeliveryIndication_t *out; + NGAP_NASNonDeliveryIndication_IEs_t *ie; + uint8_t *buffer; + uint32_t length; + DevAssert(ngap_nas_non_delivery_ind != NULL); + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, ngap_nas_non_delivery_ind->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %08x\n", + ngap_nas_non_delivery_ind->gNB_ue_ngap_id); + MSC_LOG_EVENT( + MSC_NGAP_GNB, + MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to AMF failed, no context for gNB_ue_ngap_id %08x", + ngap_nas_non_delivery_ind->gNB_ue_ngap_id); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_NASNonDeliveryIndication; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_NASNonDeliveryIndication; + out = &pdu.choice.initiatingMessage->value.choice.NASNonDeliveryIndication; + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_context_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; + ie->value.choice.NAS_PDU.buf = ngap_nas_non_delivery_ind->nas_pdu.buffer; + ie->value.choice.NAS_PDU.size = ngap_nas_non_delivery_ind->nas_pdu.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(NGAP_NASNonDeliveryIndication_IEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_Cause; + ie->criticality = NGAP_Criticality_ignore; + /* Send a dummy cause */ + ie->value.present = NGAP_NASNonDeliveryIndication_IEs__value_PR_Cause; + ie->value.choice.Cause.present = NGAP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = NGAP_CauseRadioNetwork_radio_connection_with_ue_lost; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode NAS NON delivery indication\n"); + /* Encode procedure has failed... */ + MSC_LOG_EVENT( + MSC_NGAP_GNB, + MSC_AS_TIME_FMT" Sent of NAS_NON_DELIVERY_IND to AMF failed (encoding)"); + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" NASNonDeliveryIndication initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %lu", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; +} + +//------------------------------------------------------------------------------ +int ngap_gNB_initial_ctxt_resp( + instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p) +//------------------------------------------------------------------------------ +{ + + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_InitialContextSetupResponse_t *out; + NGAP_InitialContextSetupResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(initial_ctxt_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + initial_ctxt_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + initial_ctxt_resp_p->gNB_ue_ngap_id); + return -1; + } + + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + initial_ctxt_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_InitialContextSetup; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; + out = &pdu.choice.successfulOutcome->value.choice.InitialContextSetupResponse; + /* mandatory */ + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; + //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = initial_ctxt_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (initial_ctxt_resp_p->nb_of_pdusessions){ + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceSetupListCxtRes; + for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceSetupItemCxtRes_t *item; + NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemCxtRes_t)); + + /* pDUSessionID */ + item->pDUSessionID = initial_ctxt_resp_p->pdusessions[i].pdusession_id; + + /* dLQosFlowPerTNLInformation */ + pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; + + GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); + + memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf, + initial_ctxt_resp_p->pdusessions[i].gNB_addr.buffer, + initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = initial_ctxt_resp_p->pdusessions[i].gNB_addr.length; + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0; + + NGAP_DEBUG("initial_ctxt_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", + item->pDUSessionID, + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size); + + /* associatedQosFlowList. number of 1? */ + for(int j=0; j < initial_ctxt_resp_p->pdusessions[i].nb_of_qos_flow; j++) { + NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; + ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); + + /* qosFlowIdentifier */ + ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi; + + /* qosFlowMappingIndication */ + if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { + ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); + *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; + } + ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; + item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListCxtRes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + /* optional */ + if (initial_ctxt_resp_p->nb_of_pdusessions_failed) { + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListCxtRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListCxtRes; + + for (i = 0; i < initial_ctxt_resp_p->nb_of_pdusessions_failed; i++) { + NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *item; + NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemCxtRes_t)); + /* pDUSessionID */ + item->pDUSessionID = initial_ctxt_resp_p->pdusessions_failed[i].pdusession_id; + + /* cause */ + pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t)); + pdusessionUnTransfer_p->cause.present = initial_ctxt_resp_p->pdusessions_failed[i].cause; + switch(pdusessionUnTransfer_p->cause.present) { + case NGAP_Cause_PR_radioNetwork: + pdusessionUnTransfer_p->cause.choice.radioNetwork = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_transport: + pdusessionUnTransfer_p->cause.choice.transport = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_nas: + pdusessionUnTransfer_p->cause.choice.nas = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_protocol: + pdusessionUnTransfer_p->cause.choice.protocol = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_misc: + pdusessionUnTransfer_p->cause.choice.misc = initial_ctxt_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_NOTHING: + default: + break; + } + + NGAP_DEBUG("initial context setup response: failed pdusession ID %ld\n", item->pDUSessionID); + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; + item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToSetupListCxtRes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (NGAP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_InitialContextSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics =; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode InitialContextSetupResponse\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" InitialContextSetup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + initial_ctxt_resp_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + LOG_I(NR_RRC,"Send message to sctp: NGAP_InitialContextSetupResponse\n"); + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; +} + +//------------------------------------------------------------------------------ +int ngap_gNB_ue_capabilities(instance_t instance, + ngap_ue_cap_info_ind_t *ue_cap_info_ind_p) +//------------------------------------------------------------------------------ +{ + ngap_gNB_instance_t *ngap_gNB_instance_p; + struct ngap_gNB_ue_context_s *ue_context_p; + NGAP_NGAP_PDU_t pdu; + NGAP_UERadioCapabilityInfoIndication_t *out; + NGAP_UERadioCapabilityInfoIndicationIEs_t *ie; + uint8_t *buffer; + uint32_t length; + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ue_cap_info_ind_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + ue_cap_info_ind_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", + ue_cap_info_ind_p->gNB_ue_ngap_id); + return -1; + } + + /* UE radio capabilities message can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %u, current state: %d\n", + ue_cap_info_ind_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = (NGAP_InitiatingMessage_t *)calloc(1,sizeof(NGAP_InitiatingMessage_t)); + pdu.choice.initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UERadioCapabilityInfoIndication; + pdu.choice.initiatingMessage->criticality = NGAP_Criticality_ignore; + pdu.choice.initiatingMessage->value.present = NGAP_InitiatingMessage__value_PR_UERadioCapabilityInfoIndication; + out = &pdu.choice.initiatingMessage->value.choice.UERadioCapabilityInfoIndication; + /* mandatory */ + ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_AMF_UE_NGAP_ID; + //ie->value.choice.AMF_UE_NGAP_ID = ue_context_p->amf_ue_ngap_id; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = ue_cap_info_ind_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_UERadioCapabilityInfoIndicationIEs_t *)calloc(1, sizeof(NGAP_UERadioCapabilityInfoIndicationIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_UERadioCapability; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UERadioCapabilityInfoIndicationIEs__value_PR_UERadioCapability; + ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; + ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* optional */ + //NGAP_UERadioCapabilityForPaging TBD + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + /* Encode procedure has failed... */ + NGAP_ERROR("Failed to encode UE radio capabilities indication\n"); + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" UECapabilityInfoIndication initiatingMessage gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + ue_cap_info_ind_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; +} + +//------------------------------------------------------------------------------ +int ngap_gNB_pdusession_setup_resp(instance_t instance, + ngap_pdusession_setup_resp_t *pdusession_setup_resp_p) +//------------------------------------------------------------------------------ +{ + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_PDUSessionResourceSetupResponse_t *out; + NGAP_PDUSessionResourceSetupResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(pdusession_setup_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + pdusession_setup_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + pdusession_setup_resp_p->gNB_ue_ngap_id); + return -1; + } + + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + pdusession_setup_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceSetup; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceSetupResponse; + out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceSetupResponse; + /* mandatory */ + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_setup_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (pdusession_setup_resp_p->nb_of_pdusessions > 0) { + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSURes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceSetupListSURes; + + for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceSetupItemSURes_t *item; + NGAP_PDUSessionResourceSetupResponseTransfer_t *pdusessionTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupItemSURes_t)); + + /* pDUSessionID */ + item->pDUSessionID = pdusession_setup_resp_p->pdusessions[i].pdusession_id; + + /* dLQosFlowPerTNLInformation */ + pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel = + calloc(1, sizeof(struct NGAP_GTPTunnel)); + + GTP_TEID_TO_ASN1(pdusession_setup_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); + + memcpy(pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf, + pdusession_setup_resp_p->pdusessions[i].gNB_addr.buffer, + pdusession_setup_resp_p->pdusessions[i].gNB_addr.length); + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size = pdusession_setup_resp_p->pdusessions[i].gNB_addr.length; + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.bits_unused = 0; + + NGAP_DEBUG("pdusession_setup_resp_p: pdusession ID %ld, gnb_addr %d.%d.%d.%d, SIZE %ld \n", + item->pDUSessionID, + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[0], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[1], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[2], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf[3], + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.size); + + /* associatedQosFlowList. number of 1? */ + for(int j=0; j < pdusession_setup_resp_p->pdusessions[i].nb_of_qos_flow; j++) { + NGAP_AssociatedQosFlowItem_t *ass_qos_item_p; + ass_qos_item_p = (NGAP_AssociatedQosFlowItem_t *)calloc(1, sizeof(NGAP_AssociatedQosFlowItem_t)); + + /* qosFlowIdentifier */ + ass_qos_item_p->qosFlowIdentifier = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qfi; + + /* qosFlowMappingIndication */ + //if(pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { + // ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); + // *ass_qos_item_p->qosFlowMappingIndication = pdusession_setup_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; + //} + ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); + } + + memset(&res, 0, sizeof(res)); +// res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); +// item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; +// item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; + uint8_t buffer[100]; + asn_enc_rval_t enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, + NULL, + pdusessionTransfer_p, + buffer,100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + item->pDUSessionResourceSetupResponseTransfer.buf = buffer; + item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceSetupListSURes.list, item); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (pdusession_setup_resp_p->nb_of_pdusessions_failed > 0) { + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToSetupListSURes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_PDUSessionResourceFailedToSetupListSURes; + + for (i = 0; i < pdusession_setup_resp_p->nb_of_pdusessions_failed; i++) { + NGAP_PDUSessionResourceFailedToSetupItemSURes_t *item; + NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *pdusessionUnTransfer_p = NULL; + + /* mandatory */ + item = (NGAP_PDUSessionResourceFailedToSetupItemSURes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToSetupItemSURes_t)); + /* pDUSessionID */ + item->pDUSessionID = pdusession_setup_resp_p->pdusessions_failed[i].pdusession_id; + + /* cause */ + pdusessionUnTransfer_p = (NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupUnsuccessfulTransfer_t)); + pdusessionUnTransfer_p->cause.present = pdusession_setup_resp_p->pdusessions_failed[i].cause; + switch(pdusessionUnTransfer_p->cause.present) { + case NGAP_Cause_PR_radioNetwork: + pdusessionUnTransfer_p->cause.choice.radioNetwork = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_transport: + pdusessionUnTransfer_p->cause.choice.transport = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_nas: + pdusessionUnTransfer_p->cause.choice.nas = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_protocol: + pdusessionUnTransfer_p->cause.choice.protocol = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_misc: + pdusessionUnTransfer_p->cause.choice.misc = pdusession_setup_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_NOTHING: + default: + break; + } + + NGAP_DEBUG("pdusession setup response: failed pdusession ID %ld\n", item->pDUSessionID); + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + item->pDUSessionResourceSetupUnsuccessfulTransfer.buf = res.buffer; + item->pDUSessionResourceSetupUnsuccessfulTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupUnsuccessfulTransfer, pdusessionUnTransfer_p); + + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToSetupListSURes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (NGAP_PDUSessionResourceSetupResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceSetupResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode uplink transport\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" PduSession Setup successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + pdusession_setup_resp_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + return 0; +} + +//------------------------------------------------------------------------------ +int ngap_gNB_pdusession_modify_resp(instance_t instance, + ngap_pdusession_modify_resp_t *pdusession_modify_resp_p) +//------------------------------------------------------------------------------ +{ + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_PDUSessionResourceModifyResponse_t *out; + NGAP_PDUSessionResourceModifyResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; + + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(pdusession_modify_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + pdusession_modify_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + pdusession_modify_resp_p->gNB_ue_ngap_id); + return -1; + } + + /* Uplink NAS transport can occur either during an ngap connected state + * or during initial attach (for example: NAS authentication). + */ + if (!(ue_context_p->ue_state == NGAP_UE_CONNECTED || + ue_context_p->ue_state == NGAP_UE_WAITING_CSR)) { + NGAP_WARN("You are attempting to send NAS data over non-connected " + "gNB ue ngap id: %08x, current state: %d\n", + pdusession_modify_resp_p->gNB_ue_ngap_id, ue_context_p->ue_state); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceModify; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse; + out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceModifyResponse; + /* mandatory */ + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_modify_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (pdusession_modify_resp_p->nb_of_pdusessions > 0) { + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceModifyListModRes; + + for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions; i++) { + NGAP_PDUSessionResourceModifyItemModRes_t *item; + + item = (NGAP_PDUSessionResourceModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyItemModRes_t)); + item->pDUSessionID = pdusession_modify_resp_p->pdusessions[i].pdusession_id; + + NGAP_DEBUG("pdusession_modify_resp: modified pdusession ID %ld\n", item->pDUSessionID); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceModifyListModRes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (pdusession_modify_resp_p->nb_of_pdusessions_failed > 0) { + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceFailedToModifyListModRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceFailedToModifyListModRes; + + for (i = 0; i < pdusession_modify_resp_p->nb_of_pdusessions_failed; i++) { + NGAP_PDUSessionResourceFailedToModifyItemModRes_t *item; + NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *pdusessionTransfer_p = NULL; + + item = (NGAP_PDUSessionResourceFailedToModifyItemModRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceFailedToModifyItemModRes_t)); + item->pDUSessionID = pdusession_modify_resp_p->pdusessions_failed[i].pdusession_id; + + pdusessionTransfer_p = (NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyUnsuccessfulTransfer_t)); + pdusessionTransfer_p->cause.present = pdusession_modify_resp_p->pdusessions_failed[i].cause; + + switch(pdusessionTransfer_p->cause.present) { + case NGAP_Cause_PR_radioNetwork: + pdusessionTransfer_p->cause.choice.radioNetwork = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_transport: + pdusessionTransfer_p->cause.choice.transport = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_nas: + pdusessionTransfer_p->cause.choice.nas = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_protocol: + pdusessionTransfer_p->cause.choice.protocol = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_misc: + pdusessionTransfer_p->cause.choice.misc = pdusession_modify_resp_p->pdusessions_failed[i].cause_value; + break; + + case NGAP_Cause_PR_NOTHING: + default: + break; + } + + memset(&res, 0, sizeof(res)); + res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); + item->pDUSessionResourceModifyUnsuccessfulTransfer.buf = res.buffer; + item->pDUSessionResourceModifyUnsuccessfulTransfer.size = res.result.encoded; + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceModifyUnsuccessfulTransfer, pdusessionTransfer_p); + + + NGAP_DEBUG("pdusession_modify_resp: failed pdusession ID %ld\n", item->pDUSessionID); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceFailedToModifyListModRes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + /* optional */ + if (0) { + ie = (NGAP_PDUSessionResourceModifyResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_CriticalityDiagnostics; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_CriticalityDiagnostics; + // ie->value.choice.CriticalityDiagnostics = ; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + fprintf(stderr, "start encode\n"); + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode uplink transport\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Modify successful Outcome gNB_ue_ngap_id %u amf_ue_ngap_id %u", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + pdusession_modify_resp_p->gNB_ue_ngap_id, + ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + + return 0; +} +//------------------------------------------------------------------------------ +int ngap_gNB_pdusession_release_resp(instance_t instance, + ngap_pdusession_release_resp_t *pdusession_release_resp_p) +//------------------------------------------------------------------------------ +{ + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + NGAP_NGAP_PDU_t pdu; + NGAP_PDUSessionResourceReleaseResponse_t *out; + NGAP_PDUSessionResourceReleaseResponseIEs_t *ie; + uint8_t *buffer = NULL; + uint32_t length; + int i; + /* Retrieve the NGAP gNB instance associated with Mod_id */ + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(pdusession_release_resp_p != NULL); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_gNB_get_ue_context(ngap_gNB_instance_p, + pdusession_release_resp_p->gNB_ue_ngap_id)) == NULL) { + /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ + NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: 0x%08x\n", + pdusession_release_resp_p->gNB_ue_ngap_id); + return -1; + } + + /* Prepare the NGAP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = (NGAP_SuccessfulOutcome_t *)calloc(1,sizeof(struct NGAP_SuccessfulOutcome)); + pdu.choice.successfulOutcome->procedureCode = NGAP_ProcedureCode_id_PDUSessionResourceRelease; + pdu.choice.successfulOutcome->criticality = NGAP_Criticality_reject; + pdu.choice.successfulOutcome->value.present = NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse; + out = &pdu.choice.successfulOutcome->value.choice.PDUSessionResourceReleaseResponse; + /* mandatory */ + ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, ue_context_p->amf_ue_ngap_id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + /* mandatory */ + ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = pdusession_release_resp_p->gNB_ue_ngap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + /* optional */ + if (pdusession_release_resp_p->nb_of_pdusessions_released > 0) { + ie = (NGAP_PDUSessionResourceReleaseResponseIEs_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t)); + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes; + + for (i = 0; i < pdusession_release_resp_p->nb_of_pdusessions_released; i++) { + NGAP_PDUSessionResourceReleasedItemRelRes_t *item; + item = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)calloc(1, sizeof(NGAP_PDUSessionResourceReleasedItemRelRes_t)); + + item->pDUSessionID = pdusession_release_resp_p->pdusession_release[i].pdusession_id; + if(pdusession_release_resp_p->pdusession_release[i].transfer_length > 0){ + item->pDUSessionResourceReleaseResponseTransfer.size = pdusession_release_resp_p->pdusession_release[i].transfer_length; + item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * pdusession_release_resp_p->pdusession_release[i].transfer_length); + memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf, + pdusession_release_resp_p->pdusession_release[i].transfer_buffer, + pdusession_release_resp_p->pdusession_release[i].transfer_length); + }else { + item->pDUSessionResourceReleaseResponseTransfer.size = 0; + item->pDUSessionResourceReleaseResponseTransfer.buf = NULL; + NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n"); +#ifdef ITTI_SIM + //For testing only + item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * 1); + item->pDUSessionResourceReleaseResponseTransfer.size = 1; + uint8_t temp = 0; + memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf, + &temp, + item->pDUSessionResourceReleaseResponseTransfer.size); +#endif + } + NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); + ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + NGAP_ERROR("Failed to encode release response\n"); + /* Encode procedure has failed... */ + return -1; + } + + MSC_LOG_TX_MESSAGE( + MSC_NGAP_GNB, + MSC_NGAP_AMF, + (const char *)buffer, + length, + MSC_AS_TIME_FMT" E_RAN Release successfulOutcome gNB_ue_ngap_id %u amf_ue_ngap_id %lu", + 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), + pdusession_release_resp_p->gNB_ue_ngap_id, + (uint64_t)ue_context_p->amf_ue_ngap_id); + /* UE associated signalling -> use the allocated stream */ + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, buffer, + length, ue_context_p->tx_stream); + NGAP_INFO("pdusession_release_response sended gNB_UE_NGAP_ID %u amf_ue_ngap_id %lu nb_of_pdusessions_released %d nb_of_pdusessions_failed %d\n", + pdusession_release_resp_p->gNB_ue_ngap_id, (uint64_t)ue_context_p->amf_ue_ngap_id,pdusession_release_resp_p->nb_of_pdusessions_released,pdusession_release_resp_p->nb_of_pdusessions_failed); + + return 0; +} + +int ngap_gNB_path_switch_req(instance_t instance, + ngap_path_switch_req_t *path_switch_req_p) +//------------------------------------------------------------------------------ +{ + //TODO + + return 0; +} + +int ngap_gNB_generate_PDUSESSION_Modification_Indication( + instance_t instance, + ngap_pdusession_modification_ind_t *pdusession_modification_ind) +//----------------------------------------------------------------------------- +{ + //TODO + return 0; +} + + diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.h b/openair3/NGAP/ngap_gNB_nas_procedures.h new file mode 100644 index 0000000000..e7552cd47e --- /dev/null +++ b/openair3/NGAP/ngap_gNB_nas_procedures.h @@ -0,0 +1,68 @@ +/* + * 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 ngap_gNB_nas_procedures.h + * \brief NGAP gNb NAS procedure handler + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + * \version 1.0 + * @ingroup _ngap + */ + +#ifndef NGAP_GNB_NAS_PROCEDURES_H_ +#define NGAP_GNB_NAS_PROCEDURES_H_ + +int ngap_gNB_handle_nas_downlink( + uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_p); + +int ngap_gNB_nas_non_delivery_ind(instance_t instance, + ngap_nas_non_delivery_ind_t *ngap_nas_non_delivery_ind); + +int ngap_gNB_handle_nas_first_req( + instance_t instance, ngap_nas_first_req_t *ngap_nas_first_req_p); + +int ngap_gNB_initial_ctxt_resp( + instance_t instance, ngap_initial_context_setup_resp_t *initial_ctxt_resp_p); + +int ngap_gNB_ue_capabilities(instance_t instance, + ngap_ue_cap_info_ind_t *ue_cap_info_ind_p); + +int ngap_gNB_pdusession_setup_resp(instance_t instance, + ngap_pdusession_setup_resp_t *pdusession_setup_resp_p); + +int ngap_gNB_pdusession_modify_resp(instance_t instance, + ngap_pdusession_modify_resp_t *pdusession_modify_resp_p); + +int ngap_gNB_pdusession_release_resp(instance_t instance, + ngap_pdusession_release_resp_t *pdusession_release_resp_p); + +int ngap_gNB_path_switch_req(instance_t instance, + ngap_path_switch_req_t *path_switch_req_p); + +int ngap_gNB_generate_PDUSESSION_Modification_Indication( + instance_t instance, ngap_pdusession_modification_ind_t *pdusession_modification_ind); + +#endif /* NGAP_GNB_NAS_PROCEDURES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_nnsf.c b/openair3/NGAP/ngap_gNB_nnsf.c new file mode 100644 index 0000000000..e9ec66b1b4 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_nnsf.c @@ -0,0 +1,410 @@ +/* + * 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 ngap_gNB_nnsf.c + * \brief ngap NAS node selection functions + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#include +#include + +#include "intertask_interface.h" + +#include "ngap_common.h" + +#include "ngap_gNB_defs.h" +#include "ngap_gNB_nnsf.h" + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause) +{ + struct ngap_gNB_amf_data_s *amf_data_p = NULL; + struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL; + uint8_t current_capacity = 0; + + RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) { + if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) { + /* The association between AMF and gNB is not ready for the moment, + * go to the next known AMF. + */ + if (amf_data_p->state == NGAP_GNB_OVERLOAD) { + /* AMF is overloaded. We have to check the RRC establishment + * cause and take decision to the select this AMF depending on + * the overload state. + */ + if ((cause == NGAP_RRC_CAUSE_MO_DATA) + && (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA) + || (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the AMF + * even if it is in overload state. + */ + } else { + /* The AMF is not overloaded, association is simply not ready. */ + continue; + } + } + + if (current_capacity < amf_data_p->relative_amf_capacity) { + /* We find a better AMF, keep a reference to it */ + current_capacity = amf_data_p->relative_amf_capacity; + amf_highest_capacity_p = amf_data_p; + } + } + + return amf_highest_capacity_p; +} + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause, + int selected_plmn_identity) +{ + struct ngap_gNB_amf_data_s *amf_data_p = NULL; + struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL; + uint8_t current_capacity = 0; + + RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) { + struct served_guami_s *guami_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) { + /* The association between AMF and gNB is not ready for the moment, + * go to the next known AMF. + */ + if (amf_data_p->state == NGAP_GNB_OVERLOAD) { + /* AMF is overloaded. We have to check the RRC establishment + * cause and take decision to the select this AMF depending on + * the overload state. + */ + if ((cause == NGAP_RRC_CAUSE_MO_DATA) + && (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA) + || (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the AMF + * even if it is in overload state. + */ + } else { + /* The AMF is not overloaded, association is simply not ready. */ + continue; + } + } + + /* Looking for served GUAMI PLMN Identity selected matching the one provided by the UE */ + STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) { + STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { + if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && + (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + break; + } + } + /* if found, we can stop the outer loop, too */ + if (served_plmn_p) break; + } + /* if we didn't find such a served PLMN, go on with the next AMF */ + if (!served_plmn_p) continue; + + if (current_capacity < amf_data_p->relative_amf_capacity) { + /* We find a better AMF, keep a reference to it */ + current_capacity = amf_data_p->relative_amf_capacity; + amf_highest_capacity_p = amf_data_p; + } + } + + return amf_highest_capacity_p; +} + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf_by_amf_setid(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause, + int selected_plmn_identity, + uint8_t amf_setid) +{ + struct ngap_gNB_amf_data_s *amf_data_p = NULL; + + RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) { + struct served_guami_s *guami_p = NULL; + + if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) { + /* The association between AMF and gNB is not ready for the moment, + * go to the next known AMF. + */ + if (amf_data_p->state == NGAP_GNB_OVERLOAD) { + /* AMF is overloaded. We have to check the RRC establishment + * cause and take decision to the select this AMF depending on + * the overload state. + */ + if ((cause == NGAP_RRC_CAUSE_MO_DATA) + && (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA) + || (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the AMF + * even if it is in overload state. + */ + } else { + /* The AMF is not overloaded, association is simply not ready. */ + continue; + } + } + + /* Looking for AMF code matching the one provided by NAS */ + STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) { + struct amf_set_id_s *amf_setid_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + + STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { + if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && + (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + break; + } + } + STAILQ_FOREACH(amf_setid_p, &guami_p->amf_set_ids, next) { + if (amf_setid_p->amf_set_id == amf_setid) { + break; + } + } + + /* The AMF matches the parameters provided by the NAS layer -> + * the AMF is knwown and the association is ready. + * Return the reference to the AMF to use it for this UE. + */ + if (amf_setid_p && served_plmn_p) { + return amf_data_p; + } + } + } + + /* At this point no AMF matches the selected PLMN and AMF code. In this case, + * return NULL. That way the RRC layer should know about it and reject RRC + * connectivity. */ + return NULL; +} + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause, + ngap_guami_t guami) +{ + struct ngap_gNB_amf_data_s *amf_data_p = NULL; + + RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) { + struct served_guami_s *guami_p = NULL; + + if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) { + /* The association between AMF and gNB is not ready for the moment, + * go to the next known AMF. + */ + if (amf_data_p->state == NGAP_GNB_OVERLOAD) { + /* AMF is overloaded. We have to check the RRC establishment + * cause and take decision to the select this AMF depending on + * the overload state. + */ + if ((cause == NGAP_RRC_CAUSE_MO_DATA) + && (amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((amf_data_p->overload_state == NGAP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == NGAP_RRC_CAUSE_MO_SIGNALLING) || (cause == NGAP_RRC_CAUSE_MO_DATA) + || (cause == NGAP_RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the AMF + * even if it is in overload state. + */ + } else { + /* The AMF is not overloaded, association is simply not ready. */ + continue; + } + } + + /* Looking for AMF guami matching the one provided by NAS */ + STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) { + struct served_region_id_s *region_id_p = NULL; + struct amf_set_id_s *amf_set_id_p = NULL; + struct amf_pointer_s *pointer_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + + STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { + if ((served_plmn_p->mcc == guami.mcc) && + (served_plmn_p->mnc == guami.mnc)) { + break; + } + } + + STAILQ_FOREACH(region_id_p, &guami_p->served_region_ids, next) { + if (region_id_p->amf_region_id == guami.amf_region_id) { + break; + } + } + STAILQ_FOREACH(amf_set_id_p, &guami_p->amf_set_ids, next) { + if (amf_set_id_p->amf_set_id == guami.amf_set_id) { + break; + } + } + STAILQ_FOREACH(pointer_p, &guami_p->amf_pointers, next) { + if (pointer_p->amf_pointer == guami.amf_pointer) { + break; + } + } + + /* The AMF matches the parameters provided by the NAS layer -> + * the AMF is knwown and the association is ready. + * Return the reference to the AMF to use it for this UE. + */ + if ((region_id_p != NULL) && + (amf_set_id_p != NULL) && + (pointer_p != NULL) && + (served_plmn_p != NULL)) { + return amf_data_p; + } + } + } + + /* At this point no AMF matches the provided GUAMI. In this case, return + * NULL. That way the RRC layer should know about it and reject RRC + * connectivity. */ + return NULL; +} + + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_t *instance_p, + ngap_guami_t guami) +{ + struct ngap_gNB_amf_data_s *amf_data_p = NULL; + struct ngap_gNB_amf_data_s *amf_highest_capacity_p = NULL; + uint8_t current_capacity = 0; + + + RB_FOREACH(amf_data_p, ngap_amf_map, &instance_p->ngap_amf_head) { + struct served_guami_s *guami_p = NULL; + + if (amf_data_p->state != NGAP_GNB_STATE_CONNECTED) { + /* The association between AMF and gNB is not ready for the moment, + * go to the next known AMF. + */ + if (amf_data_p->state == NGAP_GNB_OVERLOAD) { + /* AMF is overloaded. We have to check the RRC establishment + * cause and take decision to the select this AMF depending on + * the overload state. + */ + } else { + /* The AMF is not overloaded, association is simply not ready. */ + continue; + } + } + + if (current_capacity < amf_data_p->relative_amf_capacity) { + /* We find a better AMF, keep a reference to it */ + current_capacity = amf_data_p->relative_amf_capacity; + amf_highest_capacity_p = amf_data_p; + } + + /* Looking for AMF guami matching the one provided by NAS */ + STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) { + struct served_region_id_s *region_id_p = NULL; + struct amf_set_id_s *amf_set_id_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + + STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { + if ((served_plmn_p->mcc == guami.mcc) && + (served_plmn_p->mnc == guami.mnc)) { + break; + } + } + STAILQ_FOREACH(amf_set_id_p, &guami_p->amf_set_ids, next) { + if (amf_set_id_p->amf_set_id == guami.amf_set_id) { + break; + } + } + STAILQ_FOREACH(region_id_p, &guami_p->served_region_ids, next) { + if (region_id_p->amf_region_id == guami.amf_region_id) { + break; + } + } + + /* The AMF matches the parameters provided by the NAS layer -> + * the AMF is knwown and the association is ready. + * Return the reference to the AMF to use it for this UE. + */ + if ((region_id_p != NULL) && + (amf_set_id_p != NULL) && + (served_plmn_p != NULL)) { + return amf_data_p; + } + } + } + + /* At this point no AMF matches the provided GUAMI. Select the one with the + * highest relative capacity. + * In case the list of known AMF is empty, simply return NULL, that way the RRC + * layer should know about it and reject RRC connectivity. + */ + + return amf_highest_capacity_p; +} diff --git a/openair3/NGAP/ngap_gNB_nnsf.h b/openair3/NGAP/ngap_gNB_nnsf.h new file mode 100644 index 0000000000..7d43a890ea --- /dev/null +++ b/openair3/NGAP/ngap_gNB_nnsf.h @@ -0,0 +1,57 @@ +/* + * 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 ngap_gNB_nnsf.h + * \brief ngap NAS node selection functions + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#ifndef NGAP_GNB_NNSF_H_ +#define NGAP_GNB_NNSF_H_ + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause); + +struct ngap_gNB_amf_data_s * +ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause, + int selected_plmn_identity); + +struct ngap_gNB_amf_data_s* +ngap_gNB_nnsf_select_amf_by_amf_setid(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause, + int selected_plmn_identity, + uint8_t amf_setid); + +struct ngap_gNB_amf_data_s* +ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *instance_p, + ngap_rrc_establishment_cause_t cause, + ngap_guami_t guami); + +struct ngap_gNB_amf_data_s* +ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instance_t *instance_p, + ngap_guami_t guami); + +#endif /* NGAP_GNB_NNSF_H_ */ diff --git a/openair3/NGAP/ngap_gNB_overload.c b/openair3/NGAP/ngap_gNB_overload.c new file mode 100644 index 0000000000..318a2124bd --- /dev/null +++ b/openair3/NGAP/ngap_gNB_overload.c @@ -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 + */ + +/*! \file ngap_gNB_overload.c + * \brief ngap procedures for overload messages within gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + + +#include +#include +#include + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" + +#include "ngap_gNB.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_overload.h" +#include "ngap_gNB_management_procedures.h" + +#include "assertions.h" + +int ngap_gNB_handle_overload_start(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) +{ + //TODO + return 0; +} + +int ngap_gNB_handle_overload_stop(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) +{ + /* We received Overload stop message, meaning that the AMF is no more + * overloaded. This is an empty message, with only message header and no + * Information Element. + */ + DevAssert(pdu != NULL); + + ngap_gNB_amf_data_t *amf_desc_p; + + /* Non UE-associated signalling -> stream 0 */ + DevCheck(stream == 0, stream, 0, 0); + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + /* No AMF context associated */ + return -1; + } + + amf_desc_p->state = NGAP_GNB_STATE_CONNECTED; + amf_desc_p->overload_state = NGAP_NO_OVERLOAD; + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_overload.h b/openair3/NGAP/ngap_gNB_overload.h new file mode 100644 index 0000000000..0b7ab52c26 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_overload.h @@ -0,0 +1,53 @@ +/* + * 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 ngap_gNB_overload.h + * \brief ngap procedures for overload messages within gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#ifndef NGAP_GNB_OVERLOAD_H_ +#define NGAP_GNB_OVERLOAD_H_ + +/** + * \brief Handle an overload start message + **/ +// int ngap_gNB_handle_overload_start(gNB_amf_desc_t *gNB_desc_p, +// sctp_queue_item_t *packet_p, +// struct ngap_message_s *message_p); +int ngap_gNB_handle_overload_start(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +/** + * \brief Handle an overload stop message + **/ +// int ngap_gNB_handle_overload_stop(gNB_amf_desc_t *gNB_desc_p, +// sctp_queue_item_t *packet_p, +// struct ngap_message_s *message_p); +int ngap_gNB_handle_overload_stop(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +#endif /* NGAP_GNB_OVERLOAD_H_ */ diff --git a/openair3/NGAP/ngap_gNB_trace.c b/openair3/NGAP/ngap_gNB_trace.c new file mode 100644 index 0000000000..f3e216988c --- /dev/null +++ b/openair3/NGAP/ngap_gNB_trace.c @@ -0,0 +1,66 @@ +/* + * 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 ngap_gNB_trace.c + * \brief ngap trace procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#include + +#include "assertions.h" + +#include "intertask_interface.h" + +#include "ngap_gNB_default_values.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" + +#include "ngap_gNB.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_trace.h" +#include "ngap_gNB_itti_messaging.h" +#include "ngap_gNB_management_procedures.h" + + +int ngap_gNB_handle_trace_start(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu) +{ + //TODO + return 0; +} + +int ngap_gNB_handle_deactivate_trace(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *message_p) +{ + // NGAP_DeactivateTraceIEs_t *deactivate_trace_p; + // + // deactivate_trace_p = &message_p->msg.deactivateTraceIEs; + + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_trace.h b/openair3/NGAP/ngap_gNB_trace.h new file mode 100644 index 0000000000..91ea07ae80 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_trace.h @@ -0,0 +1,54 @@ +/* + * 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 ngap_gNB_trace.h + * \brief ngap trace procedures for gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#ifndef NGAP_GNB_TRACE_H_ +#define NGAP_GNB_TRACE_H_ + +// int ngap_gNB_generate_trace_failure(sctp_data_t *sctp_data_p, +// int32_t stream, +// uint32_t gNB_ue_ngap_id, +// uint32_t amf_ue_ngap_id, +// E_UTRAN_Trace_ID_t *trace_id, +// Cause_t *cause_p); + +// int ngap_gNB_handle_trace_start(gNB_amf_desc_t *gNB_desc_p, +// sctp_queue_item_t *packet_p, +// struct ngap_message_s *message_p); +int ngap_gNB_handle_trace_start(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +// int ngap_gNB_handle_deactivate_trace(gNB_amf_desc_t *gNB_desc_p, +// sctp_queue_item_t *packet_p, +// struct ngap_message_s *message_p); +int ngap_gNB_handle_deactivate_trace(uint32_t assoc_id, + uint32_t stream, + NGAP_NGAP_PDU_t *pdu); + +#endif /* NGAP_GNB_TRACE_H_ */ diff --git a/openair3/NGAP/ngap_gNB_ue_context.c b/openair3/NGAP/ngap_gNB_ue_context.c new file mode 100644 index 0000000000..8beb4d9485 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_ue_context.c @@ -0,0 +1,103 @@ +/* + * 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 ngap_gNB_ue_context.c + * \brief ngap UE context management within gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#include +#include +#include +#include + +#include "tree.h" + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" +#include "ngap_gNB_ue_context.h" + +int ngap_gNB_compare_gNB_ue_ngap_id( + struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2) +{ + if (p1->gNB_ue_ngap_id > p2->gNB_ue_ngap_id) { + return 1; + } + + if (p1->gNB_ue_ngap_id < p2->gNB_ue_ngap_id) { + return -1; + } + + return 0; +} + +/* Generate the tree management functions */ +RB_GENERATE(ngap_ue_map, ngap_gNB_ue_context_s, entries, + ngap_gNB_compare_gNB_ue_ngap_id); + +struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void) +{ + struct ngap_gNB_ue_context_s *new_p; + + new_p = malloc(sizeof(struct ngap_gNB_ue_context_s)); + + if (new_p == NULL) { + NGAP_ERROR("Cannot allocate new ue context\n"); + return NULL; + } + + memset(new_p, 0, sizeof(struct ngap_gNB_ue_context_s)); + + return new_p; +} + +struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context( + ngap_gNB_instance_t *instance_p, + uint32_t gNB_ue_ngap_id) +{ + ngap_gNB_ue_context_t temp; + + memset(&temp, 0, sizeof(struct ngap_gNB_ue_context_s)); + + /* gNB ue ngap id = 32 bits wide */ + temp.gNB_ue_ngap_id = gNB_ue_ngap_id & 0xFFFFFFFF; + + return RB_FIND(ngap_ue_map, &instance_p->ngap_ue_head, &temp); +} + +void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p) +{ + if (ue_context_p == NULL) { + NGAP_ERROR("Trying to free a NULL context\n"); + return; + } + + /* TODO: check that context is currently not in the tree of known + * contexts. + */ + + free(ue_context_p); +} diff --git a/openair3/NGAP/ngap_gNB_ue_context.h b/openair3/NGAP/ngap_gNB_ue_context.h new file mode 100644 index 0000000000..4b300c6fea --- /dev/null +++ b/openair3/NGAP/ngap_gNB_ue_context.h @@ -0,0 +1,103 @@ +/* + * 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 ngap_gNB_ue_context.h + * \brief ngap UE context management within gNB + * \author Yoshio INOUE, Masayuki HARADA + * \date 2020 + * \version 0.1 + * \email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com) + */ + +#include "tree.h" +#include "queue.h" + +#include "ngap_gNB_defs.h" + +#ifndef NGAP_GNB_UE_CONTEXT_H_ +#define NGAP_GNB_UE_CONTEXT_H_ + +// Forward declarations +struct ngap_gNB_amf_data_s; +struct ngap_ue_map; +struct gNB_amf_desc_s; + +typedef enum { + /* UE has not been registered to a AMF or UE association has failed. */ + NGAP_UE_DECONNECTED = 0x0, + /* UE ngap state is waiting for initial context setup request message. */ + NGAP_UE_WAITING_CSR = 0x1, + /* UE association is ready and bearers are established. */ + NGAP_UE_CONNECTED = 0x2, + NGAP_UE_STATE_MAX, +} ngap_ue_state; + +typedef struct ngap_gNB_ue_context_s { + /* Tree related data */ + RB_ENTRY(ngap_gNB_ue_context_s) entries; + + /* Uniquely identifies the UE between AMF and gNB within the gNB. + * This id is encoded on 32bits. + */ + uint32_t gNB_ue_ngap_id; + + /* UE id for initial connection to NGAP */ + uint16_t ue_initial_id; + + /* Uniquely identifies the UE within AMF. Encoded on 32 bits. */ + uint64_t amf_ue_ngap_id:40; + + /* Stream used for this particular UE */ + int32_t tx_stream; + int32_t rx_stream; + + /* Current UE state. */ + ngap_ue_state ue_state; + + /* Reference to AMF data this UE is attached to */ + struct ngap_gNB_amf_data_s *amf_ref; + + /* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink + * to route NAS messages correctly. 0-based, not 1-based as in TS 36.331 + * 6.2.2 RRC Connection Setup Complete! */ + int selected_plmn_identity; + + /* Reference to gNB data this UE is attached to */ + ngap_gNB_instance_t *gNB_instance; +} ngap_gNB_ue_context_t; + +int ngap_gNB_compare_gNB_ue_ngap_id( + struct ngap_gNB_ue_context_s *p1, struct ngap_gNB_ue_context_s *p2); + +/* Generate the tree management functions prototypes */ +RB_PROTOTYPE(ngap_ue_map, ngap_gNB_ue_context_s, entries, + ngap_gNB_compare_gNB_ue_ngap_id); + +struct ngap_gNB_ue_context_s *ngap_gNB_allocate_new_UE_context(void); + +struct ngap_gNB_ue_context_s *ngap_gNB_get_ue_context( + ngap_gNB_instance_t *instance_p, + uint32_t gNB_ue_ngap_id); + +void ngap_gNB_free_ue_context(struct ngap_gNB_ue_context_s *ue_context_p); + + +#endif /* NGAP_GNB_UE_CONTEXT_H_ */ diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c703501847..31ea3359da 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -89,6 +89,7 @@ uint32_t s1ap_generate_eNB_id(void) { static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, net_ip_address_t *mme_ip_address, + uint16_t mme_port, net_ip_address_t *local_ip_addr, uint16_t in_streams, uint16_t out_streams, @@ -100,9 +101,9 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, struct s1ap_eNB_mme_data_s *mme = NULL; DevAssert(instance_p != NULL); DevAssert(mme_ip_address != NULL); - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); + message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ); sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; - sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->port = mme_port; sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; sctp_new_association_req_p->in_streams = in_streams; sctp_new_association_req_p->out_streams = out_streams; @@ -112,7 +113,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, memcpy(&sctp_new_association_req_p->local_address, local_ip_addr, sizeof(*local_ip_addr)); - S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance); + S1AP_INFO("[eNB %ld] check the mme registration state\n",instance_p->instance); mme = NULL; if ( mme == NULL ) { @@ -126,6 +127,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, memcpy(&s1ap_mme_data_p->mme_s1_ip, mme_ip_address, sizeof(*mme_ip_address)); + s1ap_mme_data_p->mme_port = mme_port; for (int i = 0; i < broadcast_plmn_num; ++i) s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; @@ -141,7 +143,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, } else if (mme->state == S1AP_ENB_STATE_WAITING) { instance_p->s1ap_mme_pending_nb ++; sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id; - S1AP_INFO("[eNB %d] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n", + S1AP_INFO("[eNB %ld] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n", instance_p->instance, mme->state, mme->cnx_id, instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb); @@ -152,7 +154,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, s1ap_mme_data_p->s1ap_eNB_instance = instance_p; */ } else { - S1AP_WARN("[eNB %d] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n", + S1AP_WARN("[eNB %ld] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n", instance_p->instance, mme->state, mme->cnx_id, instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb); @@ -209,7 +211,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * new_instance->default_drx = s1ap_register_eNB->default_drx; /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ s1ap_eNB_insert_new_instance(new_instance); - S1AP_INFO("Registered new eNB[%d] and %s eNB id %u\n", + S1AP_INFO("Registered new eNB[%ld] and %s eNB id %u\n", instance, s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", s1ap_register_eNB->eNB_id); @@ -221,6 +223,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * /* Trying to connect to provided list of MME ip address */ for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { net_ip_address_t *mme_ip = &s1ap_register_eNB->mme_ip_address[index]; + uint16_t mme_port = s1ap_register_eNB->mme_port[index]; struct s1ap_eNB_mme_data_s *mme = NULL; RB_FOREACH(mme, s1ap_mme_map, &new_instance->s1ap_mme_head) { /* Compare whether IPv4 and IPv6 information is already present, in which @@ -235,6 +238,7 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * continue; s1ap_eNB_register_mme(new_instance, mme_ip, + mme_port, &s1ap_register_eNB->enb_ip_address, s1ap_register_eNB->sctp_in_streams, s1ap_register_eNB->sctp_out_streams, @@ -254,7 +258,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa DevAssert(s1ap_mme_data_p != NULL); if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n", + S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); @@ -309,13 +313,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { * Each eNB has to send an S1AP_REGISTER_ENB message with its * own parameters. */ - s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_REGISTER_ENB_REQ(received_msg)); } break; case SCTP_NEW_ASSOCIATION_RESP: { - s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); } break; @@ -326,61 +330,61 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { break; case S1AP_NAS_FIRST_REQ: { - s1ap_eNB_handle_nas_first_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_handle_nas_first_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_NAS_FIRST_REQ(received_msg)); } break; case S1AP_UPLINK_NAS: { - s1ap_eNB_nas_uplink(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_nas_uplink(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_UPLINK_NAS(received_msg)); } break; case S1AP_UE_CAPABILITIES_IND: { - s1ap_eNB_ue_capabilities(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_ue_capabilities(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_UE_CAPABILITIES_IND(received_msg)); } break; case S1AP_INITIAL_CONTEXT_SETUP_RESP: { - s1ap_eNB_initial_ctxt_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_initial_ctxt_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_INITIAL_CONTEXT_SETUP_RESP(received_msg)); } break; case S1AP_E_RAB_SETUP_RESP: { - s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_e_rab_setup_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_E_RAB_SETUP_RESP(received_msg)); } break; case S1AP_E_RAB_MODIFY_RESP: { - s1ap_eNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_e_rab_modify_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_E_RAB_MODIFY_RESP(received_msg)); } break; case S1AP_NAS_NON_DELIVERY_IND: { - s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_nas_non_delivery_ind(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_NAS_NON_DELIVERY_IND(received_msg)); } break; case S1AP_PATH_SWITCH_REQ: { - s1ap_eNB_path_switch_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_path_switch_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_PATH_SWITCH_REQ(received_msg)); } break; case S1AP_E_RAB_MODIFICATION_IND: { - s1ap_eNB_generate_E_RAB_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_generate_E_RAB_Modification_Indication(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_E_RAB_MODIFICATION_IND(received_msg)); } break; case S1AP_UE_CONTEXT_RELEASE_COMPLETE: { - s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_ue_context_release_complete(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); } break; @@ -388,9 +392,9 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { case S1AP_UE_CONTEXT_RELEASE_REQ: { s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; // test struct s1ap_eNB_ue_context_s *ue_context_p = NULL; // test - s1ap_ue_context_release_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_ue_context_release_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_UE_CONTEXT_RELEASE_REQ(received_msg)); - s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MESSAGE_GET_INSTANCE(received_msg)); // test + s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MSG_DESTINATION_INSTANCE(received_msg)); // test DevAssert(s1ap_eNB_instance_p != NULL); // test if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, @@ -403,7 +407,7 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { break; case S1AP_E_RAB_RELEASE_RESPONSE: { - s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_e_rab_release_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_E_RAB_RELEASE_RESPONSE(received_msg)); } break; diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h index d4bc6cfc0f..d8a8da8001 100644 --- a/openair3/S1AP/s1ap_eNB_defs.h +++ b/openair3/S1AP/s1ap_eNB_defs.h @@ -124,8 +124,9 @@ typedef struct s1ap_eNB_mme_data_s { /* This is the optional name provided by the MME */ char *mme_name; - /* MME S1AP IP address */ + /* MME S1AP IP address and port */ net_ip_address_t mme_s1_ip; + uint16_t mme_port; /* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max * number of 8 RATs but in our case only one is used. The LTE related pool diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c index 227a3cb6a9..8317f02731 100644 --- a/openair3/S1AP/s1ap_eNB_encoder.c +++ b/openair3/S1AP/s1ap_eNB_encoder.c @@ -137,6 +137,8 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu, res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu); *buffer = res.buffer; *len = res.result.encoded; + if (res.result.encoded == -1) + return -1; return 0; } @@ -189,6 +191,8 @@ int s1ap_eNB_encode_successfull_outcome(S1AP_S1AP_PDU_t *pdu, res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu); *buffer = res.buffer; *len = res.result.encoded; + if (res.result.encoded == -1) + return -1; return 0; } @@ -218,5 +222,7 @@ int s1ap_eNB_encode_unsuccessfull_outcome(S1AP_S1AP_PDU_t *pdu, res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu); *buffer = res.buffer; *len = res.result.encoded; + if (res.result.encoded == -1) + return -1; return 0; } diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 79501a1a09..7c233d9e14 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -188,7 +188,7 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut /* If there are no more associated MME, inform eNB app */ if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_DEREGISTERED_ENB_IND); S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0; itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); } @@ -206,7 +206,7 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut /* If there are no more pending messages, inform eNB app */ if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_REGISTER_ENB_CNF); S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb; itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); } @@ -791,7 +791,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, ue_desc_p->rx_stream = stream; ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_INITIAL_CONTEXT_SETUP_REQ); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_INITIAL_CONTEXT_SETUP_REQ); S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; ue_desc_p->ue_initial_id = 0; S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; @@ -935,7 +935,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, NULL,0, "0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ", enb_ue_s1ap_id); - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND); if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; @@ -1032,7 +1032,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, ue_desc_p->mme_ue_s1ap_id, mme_ue_s1ap_id); } - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_SETUP_REQ); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_SETUP_REQ); S1AP_E_RAB_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; S1AP_E_RAB_SETUP_REQ(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; S1AP_E_RAB_SETUP_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; @@ -1126,7 +1126,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, return -1; } - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PAGING_IND); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_PAGING_IND); /* convert S1AP_PagingIEs_t to s1ap_paging_ind_t */ /* id-UEIdentityIndexValue : convert UE Identity Index value */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, @@ -1322,7 +1322,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, if (ue_desc_p->mme_ue_s1ap_id != mme_ue_s1ap_id) { S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)", ue_desc_p->mme_ue_s1ap_id, mme_ue_s1ap_id); - message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); + message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, S1AP_E_RAB_MODIFY_RESP); S1AP_E_RAB_MODIFY_RESP (message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModReq, true); @@ -1348,7 +1348,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, return -1; } - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_MODIFY_REQ); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_MODIFY_REQ); S1AP_E_RAB_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; S1AP_E_RAB_MODIFY_REQ(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; S1AP_E_RAB_MODIFY_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; @@ -1459,7 +1459,7 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, S1AP_DEBUG("[SCTP %d] Received E-RAB release command for eNB_UE_S1AP_ID %ld mme_ue_s1ap_id %ld\n", assoc_id, enb_ue_s1ap_id, mme_ue_s1ap_id); - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_RELEASE_COMMAND); S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; /* id-NAS-PDU */ @@ -1529,7 +1529,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id, } // send a message to RRC - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PATH_SWITCH_REQ_ACK); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_PATH_SWITCH_REQ_ACK); /* mandatory */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PathSwitchRequestAcknowledgeIEs_t, ie, pathSwitchRequestAcknowledge, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); diff --git a/openair3/S1AP/s1ap_eNB_itti_messaging.c b/openair3/S1AP/s1ap_eNB_itti_messaging.c index f10c5bc623..8a6539a118 100644 --- a/openair3/S1AP/s1ap_eNB_itti_messaging.c +++ b/openair3/S1AP/s1ap_eNB_itti_messaging.c @@ -29,7 +29,7 @@ void s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uin MessageDef *message_p; sctp_data_req_t *sctp_data_req; - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_DATA_REQ); + message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_DATA_REQ); sctp_data_req = &message_p->ittiMsg.sctp_data_req; @@ -50,7 +50,7 @@ void s1ap_eNB_itti_send_nas_downlink_ind(instance_t instance, MessageDef *message_p; s1ap_downlink_nas_t *s1ap_downlink_nas; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DOWNLINK_NAS); + message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_DOWNLINK_NAS); s1ap_downlink_nas = &message_p->ittiMsg.s1ap_downlink_nas; @@ -68,7 +68,7 @@ void s1ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t asso MessageDef *message_p = NULL; sctp_close_association_t *sctp_close_association_p = NULL; - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_CLOSE_ASSOCIATION); + message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_CLOSE_ASSOCIATION); sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; sctp_close_association_p->assoc_id = assoc_id; diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index c668e32d1b..919989897a 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -80,7 +80,7 @@ int s1ap_eNB_handle_nas_first_req( s1ap_nas_first_req_p->ue_identity.gummei); if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", + S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", instance, mme_desc_p->mme_name, mme_desc_p->assoc_id, @@ -101,7 +101,7 @@ int s1ap_eNB_handle_nas_first_req( s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", + S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", instance, mme_desc_p->mme_name, mme_desc_p->assoc_id, @@ -122,7 +122,7 @@ int s1ap_eNB_handle_nas_first_req( s1ap_nas_first_req_p->selected_plmn_identity); if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", + S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", instance, mme_desc_p->mme_name, mme_desc_p->assoc_id, @@ -142,7 +142,7 @@ int s1ap_eNB_handle_nas_first_req( s1ap_nas_first_req_p->establishment_cause); if (mme_desc_p) { - S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", + S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", instance, mme_desc_p->mme_name, mme_desc_p->assoc_id); @@ -935,7 +935,7 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, /* Prepare the S1AP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; - pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABModify; + pdu.choice.successfulOutcome.procedureCode = S1AP_ProcedureCode_id_E_RABSetup; pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABSetupResponse; out = &pdu.choice.successfulOutcome.value.choice.E_RABSetupResponse; @@ -1032,7 +1032,7 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, break; } - S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); + S1AP_DEBUG("e_rab_setup_resp: failed e_rab ID %ld\n", item->value.choice.E_RABItem.e_RAB_ID); ASN_SEQUENCE_ADD(&ie->value.choice.E_RABList.list, item); } diff --git a/openair3/SCTP/sctp_eNB_itti_messaging.c b/openair3/SCTP/sctp_eNB_itti_messaging.c index 789af3f8ed..c31d4ba9ed 100644 --- a/openair3/SCTP/sctp_eNB_itti_messaging.c +++ b/openair3/SCTP/sctp_eNB_itti_messaging.c @@ -29,7 +29,7 @@ int sctp_itti_send_init_msg_multi_cnf(task_id_t task_id, instance_t instance, in MessageDef *message_p; sctp_init_msg_multi_cnf_t *sctp_init_msg_multi_cnf_p; - message_p = itti_alloc_new_message(TASK_SCTP, SCTP_INIT_MSG_MULTI_CNF); + message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_INIT_MSG_MULTI_CNF); sctp_init_msg_multi_cnf_p = &message_p->ittiMsg.sctp_init_msg_multi_cnf; @@ -45,7 +45,7 @@ int sctp_itti_send_new_message_ind(task_id_t task_id, instance_t instance, MessageDef *message_p; sctp_data_ind_t *sctp_data_ind_p; - message_p = itti_alloc_new_message(TASK_SCTP, SCTP_DATA_IND); + message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_DATA_IND); sctp_data_ind_p = &message_p->ittiMsg.sctp_data_ind; @@ -69,7 +69,7 @@ int sctp_itti_send_association_resp(task_id_t task_id, instance_t instance, MessageDef *message_p; sctp_new_association_resp_t *sctp_new_association_resp_p; - message_p = itti_alloc_new_message(TASK_SCTP, SCTP_NEW_ASSOCIATION_RESP); + message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_NEW_ASSOCIATION_RESP); sctp_new_association_resp_p = &message_p->ittiMsg.sctp_new_association_resp; @@ -89,7 +89,7 @@ int sctp_itti_send_association_ind(task_id_t task_id, instance_t instance, MessageDef *message_p; sctp_new_association_ind_t *sctp_new_association_ind_p; - message_p = itti_alloc_new_message(TASK_SCTP, SCTP_NEW_ASSOCIATION_IND); + message_p = itti_alloc_new_message(TASK_SCTP, 0, SCTP_NEW_ASSOCIATION_IND); sctp_new_association_ind_p = &message_p->ittiMsg.sctp_new_association_ind; diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 972bef0a07..2f732443be 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -364,7 +364,7 @@ sctp_handle_new_association_req( int sd = 0; int32_t assoc_id = 0; - struct sctp_event_subscribe events; + struct sctp_event_subscribe events={0}; struct sctp_cnx_list_elm_s *sctp_cnx = NULL; enum sctp_connection_type_e connection_type = SCTP_TYPE_CLIENT; @@ -413,10 +413,16 @@ sctp_handle_new_association_req( } /* Subscribe to all events */ - memset((void *)&events, 1, sizeof(struct sctp_event_subscribe)); + events.sctp_data_io_event = 1; + events.sctp_association_event = 1; + events.sctp_address_event = 1; + events.sctp_send_failure_event = 1; + events.sctp_peer_error_event = 1; + events.sctp_shutdown_event = 1; + events.sctp_partial_delivery_event = 1; if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events, - sizeof(struct sctp_event_subscribe)) < 0) { + 8) < 0) { SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n", strerror(errno)); close(sd); @@ -759,10 +765,16 @@ static int sctp_create_new_listener( } } - memset((void *)&event, 1, sizeof(struct sctp_event_subscribe)); + event.sctp_data_io_event = 1; + event.sctp_association_event = 1; + event.sctp_address_event = 1; + event.sctp_send_failure_event = 1; + event.sctp_peer_error_event = 1; + event.sctp_shutdown_event = 1; + event.sctp_partial_delivery_event = 1; if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &event, - sizeof(struct sctp_event_subscribe)) < 0) { + 8) < 0) { SCTP_ERROR("setsockopt: %s:%d\n", strerror(errno), errno); if (sd != -1) { close(sd); @@ -1104,7 +1116,7 @@ void *sctp_eNB_process_itti_msg(void *notUsed) /* We received a new connection request */ if (sctp_create_new_listener( - ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_DESTINATION_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), &received_msg->ittiMsg.sctp_init,0) < 0) { /* SCTP socket creation or bind failed... */ @@ -1119,7 +1131,7 @@ void *sctp_eNB_process_itti_msg(void *notUsed) SCTP_DEBUG("Received SCTP_INIT_MSG_MULTI_REQ\n"); multi_sd = sctp_create_new_listener( - ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_DESTINATION_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), &received_msg->ittiMsg.sctp_init_multi,1); /* We received a new connection request */ @@ -1129,27 +1141,27 @@ void *sctp_eNB_process_itti_msg(void *notUsed) } sctp_itti_send_init_msg_multi_cnf( ITTI_MSG_ORIGIN_ID(received_msg), - ITTI_MESSAGE_GET_INSTANCE(received_msg), + ITTI_MSG_DESTINATION_INSTANCE(received_msg), multi_sd); } break; case SCTP_NEW_ASSOCIATION_REQ: { - sctp_handle_new_association_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), + sctp_handle_new_association_req(ITTI_MSG_DESTINATION_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), &received_msg->ittiMsg.sctp_new_association_req); } break; case SCTP_NEW_ASSOCIATION_REQ_MULTI: { - sctp_handle_new_association_req_multi(ITTI_MESSAGE_GET_INSTANCE(received_msg), + sctp_handle_new_association_req_multi(ITTI_MSG_DESTINATION_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), &received_msg->ittiMsg.sctp_new_association_req_multi); } break; case SCTP_CLOSE_ASSOCIATION: - sctp_close_association(ITTI_MESSAGE_GET_INSTANCE(received_msg), + sctp_close_association(ITTI_MSG_DESTINATION_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), &received_msg->ittiMsg.sctp_close_association); break; @@ -1160,7 +1172,7 @@ void *sctp_eNB_process_itti_msg(void *notUsed) break; case SCTP_DATA_REQ: { - sctp_send_data(ITTI_MESSAGE_GET_INSTANCE(received_msg), + sctp_send_data(ITTI_MSG_DESTINATION_INSTANCE(received_msg), ITTI_MSG_ORIGIN_ID(received_msg), &received_msg->ittiMsg.sctp_data_req); } diff --git a/openair3/SCTP/sctp_primitives_client.c b/openair3/SCTP/sctp_primitives_client.c deleted file mode 100644 index bb71a854e1..0000000000 --- a/openair3/SCTP/sctp_primitives_client.c +++ /dev/null @@ -1,301 +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 - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -//WARNING: sctp requires libsctp-dev and -lsctp as linker option -#include -#include - -#include "assertions.h" -#include "sctp_eNB_defs.h" -#include "sctp_common.h" - -#include "sctp_primitives_client.h" - -#if defined(ENB_MODE) -# include "eNB_default_values.h" -#else -# include "mme_default_values.h" -#endif - -/* Send buffer to SCTP association */ -int sctp_send_msg(sctp_data_t *sctp_data_p, uint16_t ppid, uint16_t stream, - const uint8_t *buffer, const uint32_t length) -{ - DevAssert(buffer != NULL); - DevAssert(sctp_data_p != NULL); - - /* Send message on specified stream of the sd association - * NOTE: PPID should be defined in network order - */ - if (sctp_sendmsg(sctp_data_p->sd, (const void *)buffer, length, NULL, 0, - htonl(ppid), 0, stream, 0, 0) < 0) { - SCTP_ERROR("Sctp_sendmsg failed: %s\n", strerror(errno)); - return -1; - } - - SCTP_DEBUG("Successfully sent %d bytes to port %d on stream %d\n", - length, sctp_data_p->remote_port, stream); - - return 0; -} - -static -int sctp_handle_notifications(union sctp_notification *snp) -{ - if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) { - /* Client deconnection */ - SCTP_DEBUG("Notification received: server deconnected\n"); - } else if (SCTP_ASSOC_CHANGE == snp->sn_header.sn_type) { - /* Association has changed */ - SCTP_DEBUG("Notification received: server association changed\n"); - } else { - SCTP_DEBUG("Notification received: %d TODO\n", snp->sn_header.sn_type); - } - - /* TODO: handle more notif here */ - return 0; -} - -int sctp_run(sctp_data_t *sctp_data_p) -{ - int ret, repeat = 1; - int total_size = 0; - int sd; - struct pollfd fds; - - DevAssert(sctp_data_p != NULL); - - sd = sctp_data_p->sd; - - memset(&fds, 0, sizeof(struct pollfd)); - - fds.fd = sd; - fds.events = POLLIN; - - while (repeat == 1) { - ret = poll(&fds, 1, 0); - - if (ret < 0) { - SCTP_ERROR("[SD %d] Poll has failed (%d:%s)\n", - sd, errno, strerror(errno)); - return errno; - } else if (ret == 0) { - /* No data to read, just leave the loop */ - SCTP_DEBUG("[SD %d] Poll: no data available\n", sd); - repeat = 0; - } else { - /* Socket has some data to read */ - uint8_t buffer[SCTP_RECV_BUFFER_SIZE]; - int flags = 0; - int n; - struct sockaddr_in addr; - struct sctp_sndrcvinfo sinfo; - - socklen_t from_len; - memset((void *)&addr, 0, sizeof(struct sockaddr_in)); - from_len = (socklen_t)sizeof(struct sockaddr_in); - memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); - - n = sctp_recvmsg(sd, (void *)buffer, SCTP_RECV_BUFFER_SIZE, - (struct sockaddr *)&addr, &from_len, - &sinfo, &flags); - - if (n < 0) { - /* Other peer is deconnected */ - SCTP_ERROR("[SD %d] An error occured during read (%d:%s)\n", - sd, errno, strerror(errno)); - return 0; - } - - if (flags & MSG_NOTIFICATION) { - sctp_handle_notifications((union sctp_notification *)buffer); - } else { - struct sctp_queue_item_s *new_item_p; - - new_item_p = calloc(1, sizeof(struct sctp_queue_item_s)); - /* Normal data received */ - SCTP_DEBUG("[SD %d] Msg of length %d received from %s:%u on " - "stream %d, PPID %d, assoc_id %d\n", - sd, n, inet_ntoa(addr.sin_addr), - ntohs(addr.sin_port), sinfo.sinfo_stream, - sinfo.sinfo_ppid, sinfo.sinfo_assoc_id); - - new_item_p->local_stream = sinfo.sinfo_stream; - new_item_p->remote_port = ntohs(addr.sin_port); - new_item_p->remote_addr = addr.sin_addr.s_addr; - new_item_p->ppid = sinfo.sinfo_ppid; - new_item_p->assoc_id = sinfo.sinfo_assoc_id; - new_item_p->length = n; - new_item_p->buffer = malloc(sizeof(uint8_t) * n); - - memcpy(new_item_p->buffer, buffer, n); - - /* Insert the new packet at the tail of queue. */ - TAILQ_INSERT_TAIL(&sctp_data_p->sctp_queue, new_item_p, entry); - - /* Update queue related data */ - sctp_data_p->queue_size += n; - sctp_data_p->queue_length++; - total_size += n; - } - } - } - - return total_size; -} - -int sctp_connect_to_remote_host(char *local_ip_addr[], - int nb_local_addr, - char *remote_ip_addr, - uint16_t port, - int socket_type, - sctp_data_t *sctp_data_p) -{ - int sd = -1; - socklen_t i = 0; - - struct sctp_initmsg init; - struct sctp_event_subscribe events; - struct sockaddr *bindx_add_addr; - - DevAssert(sctp_data_p != NULL); - DevAssert(remote_ip_addr != NULL); - DevAssert(local_ip_addr != NULL); - DevCheck((socket_type == SOCK_STREAM), socket_type, 0, 0); - - SCTP_DEBUG("Creating socket type %d\n", socket_type); - - /* Create new socket */ - if ((sd = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP)) < 0) { - SCTP_ERROR("Socket creation failed: %s\n", strerror(errno)); - return -1; - } - - /* Bind to provided IP adresses */ - bindx_add_addr = calloc(nb_local_addr, sizeof(struct sockaddr)); - - for (i = 0; i < nb_local_addr; i++) { - if (inet_pton(AF_INET, local_ip_addr[i], &((struct sockaddr_in*)&bindx_add_addr[i])->sin_addr.s_addr) != 1) { - if (inet_pton(AF_INET6, local_ip_addr[i], &((struct sockaddr_in6*)&bindx_add_addr[i])->sin6_addr.s6_addr) != 1) { - continue; - } else { - ((struct sockaddr_in6*)&bindx_add_addr[i])->sin6_port = 0; - bindx_add_addr[i].sa_family = AF_INET6; - } - } else { - ((struct sockaddr_in*)&bindx_add_addr[i])->sin_port = 0; - bindx_add_addr[i].sa_family = AF_INET; - } - } - - if (sctp_bindx(sd, bindx_add_addr, nb_local_addr, SCTP_BINDX_ADD_ADDR) < 0) { - SCTP_ERROR("Socket bind failed: %s\n", strerror(errno)); - return -1; - } - - memset((void *)&init, 0, sizeof(struct sctp_initmsg)); - - /* Request a number of in/out streams */ - init.sinit_num_ostreams = SCTP_OUT_STREAMS; - init.sinit_max_instreams = SCTP_IN_STREAMS; - init.sinit_max_attempts = SCTP_MAX_ATTEMPTS; - - SCTP_DEBUG("Requesting (%d %d) (in out) streams\n", init.sinit_num_ostreams, - init.sinit_max_instreams); - - if (setsockopt(sd, IPPROTO_SCTP, SCTP_INITMSG, - &init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) { - SCTP_ERROR("Setsockopt IPPROTO_SCTP_INITMSG failed: %s\n", - strerror(errno)); - return -1; - } - - /* Subscribe to all events */ - memset((void *)&events, 1, sizeof(struct sctp_event_subscribe)); - - if (setsockopt(sd, IPPROTO_SCTP, SCTP_EVENTS, &events, - sizeof(struct sctp_event_subscribe)) < 0) { - SCTP_ERROR("Setsockopt IPPROTO_SCTP_EVENTS failed: %s\n", - strerror(errno)); - return -1; - } - - /* SOCK_STREAM socket type requires an explicit connect to the remote host - * address and port. - * Only use IPv4 for the first connection attempt - */ - { - struct sockaddr_in addr; - - memset(&addr, 0, sizeof(struct sockaddr_in)); - - if (inet_pton(AF_INET, remote_ip_addr, &addr.sin_addr.s_addr) != 1) { - SCTP_ERROR("Failed to convert ip address %s to network type\n", remote_ip_addr); - goto err; - } - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - - SCTP_DEBUG("[%d] Sending explicit connect to %s:%u\n", sd, remote_ip_addr, - port); - - /* Connect to remote host and port */ - if (sctp_connectx(sd, (struct sockaddr *)&addr, 1, NULL) < 0) { - SCTP_ERROR("Connect to %s:%u failed: %s\n", remote_ip_addr, - port, strerror(errno)); - goto err; - } - } - - /* Get SCTP status */ - sctp_get_sockinfo(sd, &sctp_data_p->instreams, &sctp_data_p->outstreams, - &sctp_data_p->assoc_id); - - sctp_data_p->sd = sd; - - sctp_get_peeraddresses(sd, &sctp_data_p->remote_ip_addresses, &sctp_data_p->nb_remote_addresses); - sctp_get_localaddresses(sd, NULL, NULL); - - TAILQ_INIT(&sctp_data_p->sctp_queue); - - return sd; - -err: - - if (sd != 0) { - close(sd); - } - - return -1; -} diff --git a/openair3/SCTP/sctp_primitives_client.h b/openair3/SCTP/sctp_primitives_client.h deleted file mode 100644 index bec4d3ed95..0000000000 --- a/openair3/SCTP/sctp_primitives_client.h +++ /dev/null @@ -1,101 +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 - */ - -#include - -#include "sctp_eNB_defs.h" - -#ifndef SCTP_PRIMITIVES_CLIENT_H_ -#define SCTP_PRIMITIVES_CLIENT_H_ - -/** @defgroup _sctp_impl_ SCTP Layer Reference Implementation - * @ingroup _ref_implementation_ - * @{ - */ - -/** \brief SCTP recv callback prototype. Will be called every time a message is - * received on socket. - * \param assocId SCTP association ID - * \param stream SCTP stream on which data had been received - * \param buffer Pointer to data (should be freed by user) - * \param length Length of message received - * @return Execution result - */ -typedef int (*sctp_recv_callback)(uint32_t assocId, - uint32_t stream, - uint8_t *buffer, - uint32_t length); - -/** \brief SCTP connected callback prototype. Will be called once the - * association is ready. - * \param args argument provided by upper layer - * \param assocId SCTP association ID - * \param instreams Number of input streams negotiated with remote peer - * \param outstreams Number of output streams negotiated with remote peer - * @return Execution result - */ -typedef int (*sctp_connected_callback)(void *args, - uint32_t assocId, - uint32_t instreams, - uint32_t outstreams); - -/** \brief Perform association to a remote peer - * \param ip_addr Peer IPv4 address - * \param port Remote port to connect to - * \param args Upper layer args that will be provided to connected callback - * \param connected_callback Connected callback - * \param recv_callback Data received callback - * @return < 0 in case of failure - */ -int sctp_connect_to_remote_host(char *local_ip_addr[], - int nb_local_addr, - char *remote_ip_addr, - uint16_t port, - int socket_type, - sctp_data_t *sctp_data_p); - -/** \brief Send message over SCTP - * \param sctp_data_p Pointer to the SCTP desc - * \param ppid Payload Protocol Identifier - * \param stream SCTP stream on which data will be sent - * \param buffer Pointer to buffer - * \param length Buffer length - * @return < 0 in case of failure - */ -int sctp_send_msg(sctp_data_t *sctp_data_p, uint16_t ppid, uint16_t stream, - const uint8_t *buffer, const uint32_t length); - -/** \brief Flush the FIFO of messages from the socket - * \param sctp_data_p - * @return < 0 in case of failure - */ -int sctp_run(sctp_data_t *sctp_data_p); - -/** \brief Properly disconnect the peer - * \param assoc_id The SCTP association ID - * @return < 0 in case of failure - */ -void sctp_disconnect(uint32_t assoc_id); - -void sctp_terminate(void); - -/* @} */ -#endif /* SCTP_PRIMITIVES_CLIENT_H_ */ diff --git a/openair3/TEST/EPC_TEST/play_scenario.c b/openair3/TEST/EPC_TEST/play_scenario.c index 3af47f21a8..ebaffdb39e 100644 --- a/openair3/TEST/EPC_TEST/play_scenario.c +++ b/openair3/TEST/EPC_TEST/play_scenario.c @@ -729,7 +729,7 @@ void *et_eNB_app_task(void *args_p) itti_receive_msg (TASK_ENB_APP, &msg_p); msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -1204,7 +1204,7 @@ int main( int argc, char **argv ) logInit(); set_glog(LOG_TRACE, LOG_MED); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); set_comp_log(ENB_APP, LOG_TRACE, LOG_MED, 1); set_comp_log(S1AP, LOG_TRACE, LOG_MED, 1); diff --git a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c index acc9b18f76..c4674e8901 100644 --- a/openair3/TEST/EPC_TEST/play_scenario_s1ap.c +++ b/openair3/TEST/EPC_TEST/play_scenario_s1ap.c @@ -1101,13 +1101,13 @@ void *et_s1ap_eNB_task(void *arg) * Each eNB has to send an S1AP_REGISTER_ENB message with its * own parameters. */ - et_s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + et_s1ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_REGISTER_ENB_REQ(received_msg)); } break; case SCTP_NEW_ASSOCIATION_RESP: { - et_s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + et_s1ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); } break; diff --git a/openair3/TEST/oaisim_mme_itti_test.c b/openair3/TEST/oaisim_mme_itti_test.c index 57cfd412ef..ecfbdb0acb 100644 --- a/openair3/TEST/oaisim_mme_itti_test.c +++ b/openair3/TEST/oaisim_mme_itti_test.c @@ -68,7 +68,7 @@ int main(int argc, char *argv[]) /* Calling each layer init function */ log_init(&mme_config); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); sctp_init(&mme_config); udp_init(&mme_config); s1ap_mme_init(&mme_config); diff --git a/openair3/TEST/oaisim_mme_test_s1c.c b/openair3/TEST/oaisim_mme_test_s1c.c index 52623463c6..94a554ab5f 100644 --- a/openair3/TEST/oaisim_mme_test_s1c.c +++ b/openair3/TEST/oaisim_mme_test_s1c.c @@ -193,7 +193,7 @@ static void *eNB_app_task(void *args_p) itti_receive_msg (TASK_ENB_APP, &msg_p); msg_name = ITTI_MSG_NAME (msg_p); - instance = ITTI_MSG_INSTANCE (msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -309,7 +309,7 @@ int main( int argc, char **argv ) /* Read eNB configuration file */ enb_properties = enb_config_init(conf_config_file_name); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); itti_wait_ready(1); diff --git a/openair3/TEST/oaisim_mme_test_s1c_s1ap.c b/openair3/TEST/oaisim_mme_test_s1c_s1ap.c index 10d43d595d..60da125073 100644 --- a/openair3/TEST/oaisim_mme_test_s1c_s1ap.c +++ b/openair3/TEST/oaisim_mme_test_s1c_s1ap.c @@ -260,13 +260,13 @@ void *s1ap_eNB_task(void *arg) * Each eNB has to send an S1AP_REGISTER_ENB message with its * own parameters. */ - s1ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &S1AP_REGISTER_ENB_REQ(received_msg)); } break; case SCTP_NEW_ASSOCIATION_RESP: { - s1ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + s1ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_new_association_resp); } break; diff --git a/openair3/TEST/test5Gnas.c b/openair3/TEST/test5Gnas.c new file mode 100644 index 0000000000..5124ad6e4d --- /dev/null +++ b/openair3/TEST/test5Gnas.c @@ -0,0 +1,34 @@ +#include +#include + +volatile int oai_exit; + +int main(int argc, char **argv) { + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + logInit(); + char *resp; + nr_user_nas_t UErrc= {0}; + NRUEcontext_t UEnas= {0}; + // Network generate identity request after a sucessfull radio attach + int size=identityRequest((void **)&resp, &UEnas); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Request:\n" ); + // UE process the message that it has received from phy layer in a "DL transfer" message + UEprocessNAS(resp, &UErrc); + // UE Scheduler should later call the response + size=identityResponse((void **)&resp, &UErrc); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Response:\n" ); + // Now the gNB process the identity response + processNAS(resp, &UEnas); + // gNB scheduler should call the next query + size=authenticationRequest((void **)&resp, &UEnas); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication request:\n" ); + // as above + UEprocessNAS(resp, &UErrc); + size=authenticationResponse((void **)&resp, &UErrc); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication response:\n" ); + processNAS(resp, &UEnas); + return 0; +} diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index 90ee87900d..515dd9a17f 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -257,7 +257,7 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) forwarded_buffer = itti_malloc(TASK_UDP, udp_sock_pP->task_id, n*sizeof(uint8_t)); DevAssert(forwarded_buffer != NULL); memcpy(forwarded_buffer, l_buffer, n); - message_p = itti_alloc_new_message(TASK_UDP, UDP_DATA_IND); + message_p = itti_alloc_new_message(TASK_UDP, 0, UDP_DATA_IND); DevAssert(message_p != NULL); udp_data_ind_p = &message_p->ittiMsg.udp_data_ind; udp_data_ind_p->buffer = forwarded_buffer; @@ -318,7 +318,7 @@ void *udp_eNB_task(void *args_p) if (received_message_p != NULL) { //msg_name = ITTI_MSG_NAME (received_message_p); - //instance = ITTI_MSG_INSTANCE (received_message_p); + //instance = ITTI_MSG_DESTINATION_INSTANCE (received_message_p); switch (ITTI_MSG_ID(received_message_p)) { case UDP_INIT: { diff --git a/openair3/UICC/usim_interface.c b/openair3/UICC/usim_interface.c new file mode 100644 index 0000000000..15a4e2e540 --- /dev/null +++ b/openair3/UICC/usim_interface.c @@ -0,0 +1,92 @@ +/* +* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The OpenAirInterface Software Alliance licenses this file to You under +* the OAI Public License, Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.openairinterface.org/?page_id=698 +* +* Author and copyright: Laurent Thomas, open-cells.com +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*------------------------------------------------------------------------------- +* For more information about the OpenAirInterface (OAI) Software Alliance: +* contact@openairinterface.org +*/ + +#include +#include + +#define UICC_SECTION "uicc" +#define UICC_CONFIG_HELP_OPTIONS " list of comma separated options to interface a simulated (real UICC to be developped). Available options: \n"\ + " imsi: user imsi\n"\ + " key: cyphering key\n"\ + " opc: cyphering OPc\n" +/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* configuration parameters for the rfsimulator device */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define UICC_PARAMS_DESC {\ + {"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"", TYPE_STRING, 0 },\ + {"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\ + {"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"", TYPE_STRING, 0 },\ + {"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"", TYPE_STRING, 0 },\ + {"amf", "USIM amf\n", 0, strptr:&(uicc->amfStr), defstrval:"8000", TYPE_STRING, 0 },\ + {"sqn", "USIM sqn\n", 0, strptr:&(uicc->sqnStr), defstrval:"000000", TYPE_STRING, 0 },\ + }; + +const char *hexTable="0123456789abcdef"; +static inline uint8_t mkDigit(unsigned char in) { + for (int i=0; i<16; i++) + if (in==hexTable[i]) + return i; + LOG_E(SIM,"Impossible hexa input: %c\n",in); + return 0; +} + +static inline void to_hex(char *in, uint8_t *out, int size) { + for (size_t i=0; in[i]!=0 && i < size*2 ; i+=2) { + *out++=(mkDigit(in[i]) << 4) | mkDigit(in[i+1]); + } +} + +uicc_t *init_uicc(char *sectionName) { + uicc_t *uicc=(uicc_t *)calloc(sizeof(uicc_t),1); + paramdef_t uicc_params[] = UICC_PARAMS_DESC; + // here we call usim simulation, but calling actual usim is quite simple + // the code is in open-cells.com => program_uicc open source + // we can read the IMSI from the USIM + // key, OPc, sqn, amf don't need to be read from the true USIM + int ret = config_get( uicc_params,sizeof(uicc_params)/sizeof(paramdef_t),sectionName); + AssertFatal(ret >= 0, "configuration couldn't be performed"); + LOG_I(SIM, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr); + to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) ); + to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) ); + to_hex(uicc->sqnStr,uicc->sqn, sizeof(uicc->sqn) ); + to_hex(uicc->amfStr,uicc->amf, sizeof(uicc->amf) ); + return uicc; +} + +void uicc_milenage_generate(uint8_t *autn, uicc_t *uicc) { + // here we call usim simulation, but calling actual usim is quite simple + // the code is in open-cells.com => program_uicc open source + milenage_generate(uicc->opc, uicc->amf, uicc->key, + uicc->sqn, uicc->rand, autn, uicc->ik, uicc->ck, uicc->milenage_res); + log_dump(SIM,uicc->opc,sizeof(uicc->opc), LOG_DUMP_CHAR,"opc:"); + log_dump(SIM,uicc->amf,sizeof(uicc->amf), LOG_DUMP_CHAR,"amf:"); + log_dump(SIM,uicc->key,sizeof(uicc->key), LOG_DUMP_CHAR,"key:"); + log_dump(SIM,uicc->sqn,sizeof(uicc->sqn), LOG_DUMP_CHAR,"sqn:"); + log_dump(SIM,uicc->rand,sizeof(uicc->rand), LOG_DUMP_CHAR,"rand:"); + log_dump(SIM,uicc->ik,sizeof(uicc->ik), LOG_DUMP_CHAR,"milenage output ik:"); + log_dump(SIM,uicc->ck,sizeof(uicc->ck), LOG_DUMP_CHAR,"milenage output ck:"); + log_dump(SIM,uicc->milenage_res,sizeof(uicc->milenage_res), LOG_DUMP_CHAR,"milenage output res:"); + log_dump(SIM,autn,sizeof(autn), LOG_DUMP_CHAR,"milenage output autn:"); +} + diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h new file mode 100644 index 0000000000..e8f241c1e8 --- /dev/null +++ b/openair3/UICC/usim_interface.h @@ -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 +* +* Author and copyright: Laurent Thomas, open-cells.comopenair3/UICC/usim_interface.h +* +* 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 USIM_INTERFACE_H +#define USIM_INTERFACE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common_lib.h" + +/* 3GPP glossary +RES RESponse +XRES eXpected RESponse +HRES Hash RESponse +HXRES Hash eXpected RESponse +So, RES can be either milenage res, or received response, so hash of milenage res +*/ + +typedef struct { + char *imsiStr; + char *keyStr; + char *opcStr; + char *amfStr; + char *sqnStr; + uint8_t key[16]; + uint8_t opc[16]; + uint8_t amf[2]; + uint8_t sqn[6]; + int nmc_size; + uint8_t rand[16]; + uint8_t autn[16]; + uint8_t ak[6]; + uint8_t akstar[6]; + uint8_t ck[16]; + uint8_t ik[16]; + uint8_t milenage_res[8]; +} uicc_t; + +/* + * Read the configuration file, section name variable to be able to manage several UICC + */ +uicc_t *init_uicc(char *sectionName); +void uicc_milenage_generate(uint8_t * autn, uicc_t *uicc); +#endif diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index d28c9acccb..cfb2c8cdfc 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -81,6 +81,23 @@ do { \ ((buf)[1]); \ } while(0) +/* Convert an integer on 24 bits to the given bUFFER */ +#define INT24_TO_BUFFER(x, buf) \ +do { \ + (buf)[0] = (x) >> 16; \ + (buf)[1] = (x) >> 8; \ + (buf)[2] = (x); \ +} while(0) + +/* Convert an array of char containing vALUE to x */ +#define BUFFER_TO_INT24(buf, x) \ +do { \ + x = ((buf)[0] << 16) | \ + ((buf)[1] << 8 ) | \ + ((buf)[2]); \ +} while(0) + + /* Convert an integer on 32 bits to the given bUFFER */ #define INT32_TO_BUFFER(x, buf) \ do { \ @@ -126,6 +143,21 @@ do { \ (aSN)->bits_unused = 0; \ } while(0) + +#define INT24_TO_OCTET_STRING(x, aSN) \ +do { \ + (aSN)->buf = calloc(3, sizeof(uint8_t)); \ + INT24_TO_BUFFER(x, ((aSN)->buf)); \ + (aSN)->size = 3; \ +} while(0) + +#define INT24_TO_BIT_STRING(x, aSN) \ +do { \ + INT24_TO_OCTET_STRING(x, aSN); \ + (aSN)->bits_unused = 0; \ +} while(0) + + #define INT8_TO_OCTET_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(1, sizeof(uint8_t)); \ @@ -137,6 +169,25 @@ do { \ #define M_TMSI_TO_OCTET_STRING INT32_TO_OCTET_STRING #define MME_GID_TO_OCTET_STRING INT16_TO_OCTET_STRING +#define AMF_REGION_TO_BIT_STRING(x, aSN) \ + do { \ + INT8_TO_OCTET_STRING(x, aSN); \ + (aSN)->bits_unused = 0; \ +} while(0) + +#define AMF_SETID_TO_BIT_STRING(x, aSN) \ + do { \ + INT16_TO_OCTET_STRING(x, aSN); \ + (aSN)->bits_unused = 6; \ +} while(0) + +#define AMF_POINTER_TO_BIT_STRING(x, aSN) \ + do { \ + INT8_TO_OCTET_STRING(x, aSN); \ + (aSN)->bits_unused = 2; \ +} while(0) + + #define ENCRALG_TO_BIT_STRING(encralg, bitstring) \ do { \ (bitstring)->size=2; \ @@ -197,6 +248,12 @@ do { \ BUFFER_TO_INT16((aSN)->buf, x); \ } while(0) +#define OCTET_STRING_TO_INT24(aSN, x) \ +do { \ + DevCheck((aSN)->size == 2 || (aSN)->size == 3, (aSN)->size, 0, 0); \ + BUFFER_TO_INT24((aSN)->buf, x); \ +} while(0) + #define OCTET_STRING_TO_INT32(aSN, x) \ do { \ DevCheck((aSN)->size == 4, (aSN)->size, 0, 0); \ @@ -445,6 +502,19 @@ do { \ (bITsTRING)->size = 3; \ (bITsTRING)->bits_unused = 4; \ } while(0) + + +#define MACRO_GNB_ID_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = ((mACRO) >> 20); \ + (bITsTRING)->buf[1] = (mACRO) >> 12; \ + (bITsTRING)->buf[2] = (mACRO) >> 4; \ + (bITsTRING)->buf[3] = ((mACRO) & 0x0f) << 4; \ + (bITsTRING)->size = 4; \ + (bITsTRING)->bits_unused = 4; \ +} while(0) + /* TS 36.413 v10.9.0 section 9.2.1.38: * E-UTRAN CGI/Cell Identity * The leftmost bits of the Cell @@ -462,6 +532,19 @@ do { \ (bITsTRING)->bits_unused = 4; \ } while(0) +#define MACRO_GNB_ID_TO_CELL_IDENTITY(mACRO, cELL_iD, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(5, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = ((mACRO) >> 20); \ + (bITsTRING)->buf[1] = (mACRO) >> 12; \ + (bITsTRING)->buf[2] = (mACRO) >> 4; \ + (bITsTRING)->buf[3] = (((mACRO) & 0x0f) << 4) | ((cELL_iD) >> 4); \ + (bITsTRING)->buf[4] = ((cELL_iD) & 0x0f) << 4; \ + (bITsTRING)->size = 5; \ + (bITsTRING)->bits_unused = 4; \ +} while(0) + + /* Used to format an uint32_t containing an ipv4 address */ #define IPV4_ADDR "%u.%u.%u.%u" #define IPV4_ADDR_FORMAT(aDDRESS) \ diff --git a/openshift/README.md b/openshift/README.md new file mode 100644 index 0000000000..b7409ab945 --- /dev/null +++ b/openshift/README.md @@ -0,0 +1,107 @@ + + + + + +
+ + + + + + OpenShift Build and Usage Procedures +
+ +----- + +**CAUTION: this is experimental. Still a lot to be done.** + +----- + +# 1. Build pre-requisites # + +To build our RAN images, we SHALL use the `codeready-builder-for-rhel-8-x86_64-rpms` repository with all the proper development libraries. + +This repository is not directly accessible from the UBI RHEL8 image (`registry.access.redhat.com/ubi8/ubi:latest`). + +So we need to copy from a register RHEL8 machine certificates and subsccription manager configuration files. + +SO on a `RHEL8` physical machine (or a virtual machine) connected to the OpenShift Cluster, recover the entitlement and the RH subscription manager configs: + +```bash +oc create configmap rhsm-conf --from-file /etc/rhsm/rhsm.conf +oc create configmap rhsm-ca --from-file /etc/rhsm/ca/redhat-uep.pem + +oc create secret generic etc-pki-entitlement --from-file /etc/pki/entitlement/{NUMBER_ON_YOUR_COMPUTER}.pem --from-file /etc/pki/entitlement/{NUMBER_ON_YOUR_COMPUTER}-key.pem +``` + +These configmaps and secret will be shared by all the build configs in your OC project. No need to do it each time. + +**CAUTION: these files expire every month or so. If you have done a build on your OC project and try again a few weeks later, you may need to re-copy them**. + +```bash +oc delete secret etc-pki-entitlement +oc delete cm rhsm-conf +oc delete cm rhsm-ca +``` + +**LAST POINT: your OC project SHALL be `oai`.** + +# 2. Build the Builder shared image # + +In our Eurecom/OSA environment we need to pass a GIT proxy. + +2 things are impacted by this situation: + +* In `openshift/oai-ran-rh8-build-config.yml` file + * `httpProxy: http://proxy.eurecom.fr:8080` + * `httpsProxy: https://proxy.eurecom.fr:8080` +* Add a environment variable to the build config + +```bash +oc apply -f openshift/oai-ran-rh8-image-stream.yml +oc apply -f openshift/oai-ran-rh8-build-config.yml +oc set env bc/oai-ran-rhel8-build-config NEEDED_GIT_PROXY=http://proxy.eurecom.fr:8080 +oc start-build oai-ran-rhel8-build-config --follow +``` + +In case you do NOT require a GIT proxy: **you SHALL remove the 2 lines in `openshift/oai-ran-rh8-build-config.yml` file.** + +And no need to add a `NEEDED_GIT_PROXY` variable to the build config. + +```bash +oc apply -f openshift/oai-ran-rh8-image-stream.yml +oc apply -f openshift/modified-oai-ran-rh8-build-config.yml +oc start-build oai-ran-rhel8-build-config --follow +``` + +After a while it should be successful. + +# 3. Build an OAI target image # + +For the example the eNB: + +```bash +oc apply -f openshift/oai-enb-rh8-image-stream.yml +oc apply -f openshift/oai-enb-rh8-build-config.yml +oc start-build oai-enb-rh8-build-config --follow +``` + +**CAUTION: if you are pushing modifications to the branch you are using, it won't be taken into account besides the Dockerfile.** + +**Because the source files are copied during the shared image creation.** + +**Only way to regenerate images w/ modified source code is to re-start from step #2.** + +# 4. Deployment using HELM charts # + +**CAUTION: even more experimental.** + +Helm charts are located in another repository: + +```bash +git clone https://github.com/OPENAIRINTERFACE/openair-k8s.git +cd openair-k8s +git checkout helm-deployment-S6a-S1C-S1U-in-network-18-with-enb +helm install mme /path-to-your-cloned/openair-k8s/charts/oai-mme/ +``` diff --git a/openshift/oai-enb-build-config.yml b/openshift/oai-enb-build-config.yml new file mode 100644 index 0000000000..3f6875c50d --- /dev/null +++ b/openshift/oai-enb-build-config.yml @@ -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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-enb-build-config" +spec: + runPolicy: "Serial" + source: + #still needed for the target image + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + secrets: + - secret: + name: etc-pki-entitlement + destinationDir: etc-pki-entitlement + configMaps: + - configMap: + name: rhsm-conf + destinationDir: rhsm-conf + - configMap: + name: rhsm-ca + destinationDir: rhsm-ca + + strategy: + #using both builder image and target image docker + dockerStrategy: + dockerfilePath: "docker/Dockerfile.eNB.rhel7.oc4-4" + output: + to: + kind: "ImageStreamTag" + name: "oai-enb:latest" diff --git a/openshift/oai-enb-image-stream.yml b/openshift/oai-enb-image-stream.yml new file mode 100644 index 0000000000..94ee13e50f --- /dev/null +++ b/openshift/oai-enb-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-enb + namespace: oai +status: + tag: latest + diff --git a/openshift/oai-enb-rh8-build-config.yml b/openshift/oai-enb-rh8-build-config.yml new file mode 100644 index 0000000000..e715fc5733 --- /dev/null +++ b/openshift/oai-enb-rh8-build-config.yml @@ -0,0 +1,48 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-enb-rh8-build-config" +spec: + runPolicy: "Serial" + source: + #still needed for the target image + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + strategy: + #using both builder image and target image docker + dockerStrategy: + dockerfilePath: "docker/Dockerfile.eNB.rhel8.2.oc4-4" + nodeSelector: + kubernetes.io/hostname: dedale.5glab.nsa.eurecom.fr + resources: + requests: + ephemeral-storage: "8Gi" + output: + to: + kind: "ImageStreamTag" + name: "oai-enb:rhel8-latest" diff --git a/openshift/oai-enb-rh8-image-stream.yml b/openshift/oai-enb-rh8-image-stream.yml new file mode 100644 index 0000000000..9d1cfebd54 --- /dev/null +++ b/openshift/oai-enb-rh8-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-enb + namespace: oai +status: + tag: rhel8-latest + diff --git a/openshift/oai-gnb-build-config.yml b/openshift/oai-gnb-build-config.yml new file mode 100644 index 0000000000..b0c99959d1 --- /dev/null +++ b/openshift/oai-gnb-build-config.yml @@ -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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-gnb-build-config" +spec: + runPolicy: "Serial" + source: + #still needed for the target image + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + secrets: + - secret: + name: etc-pki-entitlement + destinationDir: etc-pki-entitlement + configMaps: + - configMap: + name: rhsm-conf + destinationDir: rhsm-conf + - configMap: + name: rhsm-ca + destinationDir: rhsm-ca + + strategy: + #using both builder image and target image docker + dockerStrategy: + dockerfilePath: "docker/Dockerfile.gNB.rhel7.oc4-4" + output: + to: + kind: "ImageStreamTag" + name: "oai-gnb:latest" diff --git a/openshift/oai-gnb-image-stream.yml b/openshift/oai-gnb-image-stream.yml new file mode 100644 index 0000000000..22a6c157d2 --- /dev/null +++ b/openshift/oai-gnb-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-gnb + namespace: oai +status: + tag: latest + diff --git a/openshift/oai-gnb-rh8-build-config.yml b/openshift/oai-gnb-rh8-build-config.yml new file mode 100644 index 0000000000..aa3553c1e4 --- /dev/null +++ b/openshift/oai-gnb-rh8-build-config.yml @@ -0,0 +1,48 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-gnb-rh8-build-config" +spec: + runPolicy: "Serial" + source: + #still needed for the target image + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + strategy: + #using both builder image and target image docker + dockerStrategy: + dockerfilePath: "docker/Dockerfile.gNB.rhel8.2.oc4-4" + nodeSelector: + kubernetes.io/hostname: dedale.5glab.nsa.eurecom.fr + resources: + requests: + ephemeral-storage: "15Gi" + output: + to: + kind: "ImageStreamTag" + name: "oai-gnb:rhel8-latest" diff --git a/openshift/oai-gnb-rh8-image-stream.yml b/openshift/oai-gnb-rh8-image-stream.yml new file mode 100644 index 0000000000..2e04e94f5b --- /dev/null +++ b/openshift/oai-gnb-rh8-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-gnb + namespace: oai +status: + tag: rhel8-latest + diff --git a/openshift/oai-lte-ue-rh8-build-config.yml b/openshift/oai-lte-ue-rh8-build-config.yml new file mode 100644 index 0000000000..f077e4cb26 --- /dev/null +++ b/openshift/oai-lte-ue-rh8-build-config.yml @@ -0,0 +1,48 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-lte-ue-rh8-build-config" +spec: + runPolicy: "Serial" + source: + #still needed for the target image + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + strategy: + #using both builder image and target image docker + dockerStrategy: + dockerfilePath: "docker/Dockerfile.lteUE.rhel8.2.oc4-4" + nodeSelector: + kubernetes.io/hostname: dedale.5glab.nsa.eurecom.fr + resources: + requests: + ephemeral-storage: "8Gi" + output: + to: + kind: "ImageStreamTag" + name: "oai-lte-ue:rhel8-latest" diff --git a/openshift/oai-lte-ue-rh8-image-stream.yml b/openshift/oai-lte-ue-rh8-image-stream.yml new file mode 100644 index 0000000000..09aeb2a766 --- /dev/null +++ b/openshift/oai-lte-ue-rh8-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-lte-ue + namespace: oai +status: + tag: rhel8-latest + diff --git a/openshift/oai-nr-ue-rh8-build-config.yml b/openshift/oai-nr-ue-rh8-build-config.yml new file mode 100644 index 0000000000..b3367f6ab6 --- /dev/null +++ b/openshift/oai-nr-ue-rh8-build-config.yml @@ -0,0 +1,48 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-nr-ue-rh8-build-config" +spec: + runPolicy: "Serial" + source: + #still needed for the target image + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + strategy: + #using both builder image and target image docker + dockerStrategy: + dockerfilePath: "docker/Dockerfile.nrUE.rhel8.2.oc4-4" + nodeSelector: + kubernetes.io/hostname: dedale.5glab.nsa.eurecom.fr + resources: + requests: + ephemeral-storage: "8Gi" + output: + to: + kind: "ImageStreamTag" + name: "oai-nr-ue:rhel8-latest" diff --git a/openshift/oai-nr-ue-rh8-image-stream.yml b/openshift/oai-nr-ue-rh8-image-stream.yml new file mode 100644 index 0000000000..e61cc0dfde --- /dev/null +++ b/openshift/oai-nr-ue-rh8-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-nr-ue + namespace: oai +status: + tag: rhel8-latest + diff --git a/openshift/oai-ran-build-config.yml b/openshift/oai-ran-build-config.yml new file mode 100644 index 0000000000..39d7a40f6d --- /dev/null +++ b/openshift/oai-ran-build-config.yml @@ -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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-ran-build-config" +spec: + runPolicy: "Serial" + source: + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + secrets: + - secret: + name: etc-pki-entitlement + destinationDir: etc-pki-entitlement + configMaps: + - configMap: + name: rhsm-conf + destinationDir: rhsm-conf + - configMap: + name: rhsm-ca + destinationDir: rhsm-ca + strategy: + dockerStrategy: + dockerfilePath: "docker/Dockerfile.ran.rhel7.oc4-4" + output: + to: + kind: "ImageStreamTag" + name: "oai-ran:latest" diff --git a/openshift/oai-ran-image-stream.yml b/openshift/oai-ran-image-stream.yml new file mode 100644 index 0000000000..e1ef9d0b31 --- /dev/null +++ b/openshift/oai-ran-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-ran + namespace: oai +status: + tag: latest + diff --git a/openshift/oai-ran-rh8-build-config.yml b/openshift/oai-ran-rh8-build-config.yml new file mode 100644 index 0000000000..3d27b7cb5c --- /dev/null +++ b/openshift/oai-ran-rh8-build-config.yml @@ -0,0 +1,57 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +kind: BuildConfig +apiVersion: build.openshift.io/v1 +metadata: + name: "oai-ran-rhel8-build-config" +spec: + runPolicy: "Serial" + source: + git: + uri: "https://gitlab.eurecom.fr/oai/openairinterface5g.git" + ref: "develop" + httpProxy: http://proxy.eurecom.fr:8080 + httpsProxy: https://proxy.eurecom.fr:8080 + secrets: + - secret: + name: etc-pki-entitlement + destinationDir: etc-pki-entitlement + configMaps: + - configMap: + name: rhsm-conf + destinationDir: rhsm-conf + - configMap: + name: rhsm-ca + destinationDir: rhsm-ca + strategy: + dockerStrategy: + dockerfilePath: "docker/Dockerfile.ran.rhel8.2.oc4-4" + nodeSelector: + kubernetes.io/hostname: dedale.5glab.nsa.eurecom.fr + resources: + requests: + ephemeral-storage: "5Gi" + output: + to: + kind: "ImageStreamTag" + name: "oai-ran:rhel8-latest" diff --git a/openshift/oai-ran-rh8-image-stream.yml b/openshift/oai-ran-rh8-image-stream.yml new file mode 100644 index 0000000000..f6f4f8614f --- /dev/null +++ b/openshift/oai-ran-rh8-image-stream.yml @@ -0,0 +1,30 @@ +#/* +# * 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 +# */ +#--------------------------------------------------------------------- +# +apiVersion: v1 +kind: ImageStream +metadata: + name: oai-ran + namespace: oai +status: + tag: rhel8-latest + diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index 3066f0906f..3a69d4c991 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -112,6 +112,9 @@ int load_lib(openair0_device *device, else deflibname=OAI_RF_LIBNAME; shlib_fdesc[0].fname="device_init"; + } else if (flag == RAU_REMOTE_THIRDPARTY_RADIO_HEAD) { + deflibname=OAI_THIRDPARTY_TP_LIBNAME; + shlib_fdesc[0].fname="transport_init"; } else { deflibname=OAI_TP_LIBNAME; shlib_fdesc[0].fname="transport_init"; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 778c8165eb..85ee80ea7c 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -41,6 +41,8 @@ #define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ #define OAI_TP_LIBNAME "oai_transpro" +/* name of shared library implementing a third-party transport */ +#define OAI_THIRDPARTY_TP_LIBNAME "thirdparty_transpro" /* name of shared library implementing the rf simulator */ #define OAI_RFSIM_LIBNAME "rfsimulator" /* name of shared library implementing the basic simulator */ @@ -51,10 +53,9 @@ /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 #define RAU_REMOTE_RADIO_HEAD 1 - +#define RAU_REMOTE_THIRDPARTY_RADIO_HEAD 2 #define MAX_WRITE_THREAD_PACKAGE 10 #define MAX_WRITE_THREAD_BUFFER_SIZE 8 - #ifndef MAX_CARDS #define MAX_CARDS 8 #endif @@ -367,12 +368,22 @@ struct openair0_device_t { /*! \brief Called to send samples to the RF target @param device pointer to the device structure specific to the RF hardware target @param timestamp The timestamp at whicch the first sample MUST be sent - @param buff Buffer which holds the samples + @param buff Buffer which holds the samples (2 dimensional) + @param nsamps number of samples to be sent + @param number of antennas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied + */ + int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); + + /*! \brief Called to send samples to the RF target + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at whicch the first sample MUST be sent + @param buff Buffer which holds the samples (1 dimensional) @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas @param flags flags must be set to TRUE if timestamp parameter needs to be applied */ - int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); + int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int antenna_id, int flags); /*! \brief Receive samples from hardware. * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for @@ -382,10 +393,24 @@ struct openair0_device_t { * \param[out] ptimestamp the time at which the first sample was received. * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps. * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. - * \param antenna_id Index of antenna for which to receive samples + * \param num_antennas number of antennas from which to receive samples * \returns the number of sample read */ - int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id); + + int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int num_antennas); + + /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns. + * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param antenna_id Index of antenna from which samples were received + * \returns the number of sample read + */ + int (*trx_read_func2)(openair0_device *device, openair0_timestamp *ptimestamp, void *buff, int nsamps,int *antenna_id); /*! \brief print the device statistics * \param device the hardware to use @@ -431,6 +456,25 @@ struct openair0_device_t { */ void (*configure_rru)(int idx, void *arg); +/*! \brief Pointer to generic RRU private information + */ + + void *thirdparty_priv; + + /*! \brief Callback for Third-party RRU Initialization routine + \param device the hardware configuration to use + */ + int (*thirdparty_init)(openair0_device *device); + /*! \brief Callback for Third-party RRU Cleanup routine + \param device the hardware configuration to use + */ + int (*thirdparty_cleanup)(openair0_device *device); + + /*! \brief Callback for Third-party start streaming routine + \param device the hardware configuration to use + */ + int (*thirdparty_startstreaming)(openair0_device *device); + /*! \brief RRU Configuration callback * \param idx RU index * \param arg pointer to capabilities or configuration diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c index d893c66b52..9c0a9e3f65 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c @@ -102,23 +102,15 @@ int eth_socket_init_raw(openair0_device *device) { eth->local_addrd_ll.sll_family = AF_PACKET; eth->local_addrd_ll.sll_ifindex = eth->if_index.ifr_ifindex; /* hear traffic from specific protocol*/ - if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - eth->local_addrd_ll.sll_protocol = htons(0xbffe); - } else{ - eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc); - eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd); - } + eth->local_addrc_ll.sll_protocol = htons((short)device->eth_params->my_portc); + eth->local_addrd_ll.sll_protocol = htons((short)device->eth_params->my_portd); + eth->local_addrc_ll.sll_halen = ETH_ALEN; eth->local_addrc_ll.sll_pkttype = PACKET_OTHERHOST; eth->local_addrd_ll.sll_halen = ETH_ALEN; eth->local_addrd_ll.sll_pkttype = PACKET_OTHERHOST; eth->addr_len = sizeof(struct sockaddr_ll); - if ((eth->flags != ETH_RAW_IF5_MOBIPASS ) && - (bind(eth->sockfdc,(struct sockaddr *)ð->local_addrc_ll,eth->addr_len)<0)) { - perror("ETHERNET: Cannot bind to socket (control)"); - exit(0); - } if (bind(eth->sockfdd,(struct sockaddr *)ð->local_addrd_ll,eth->addr_len)<0) { perror("ETHERNET: Cannot bind to socket (user)"); exit(0); @@ -127,12 +119,9 @@ int eth_socket_init_raw(openair0_device *device) { /* Construct the Ethernet header */ ether_aton_r(local_mac, (struct ether_addr *)(&(eth->ehd.ether_shost))); ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->ehd.ether_dhost))); - if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - eth->ehd.ether_type = htons(0xbffe); - } else { - eth->ehc.ether_type = htons((short)device->eth_params->my_portc); - eth->ehd.ether_type = htons((short)device->eth_params->my_portd); - } + eth->ehc.ether_type = htons((short)device->eth_params->my_portc); + eth->ehd.ether_type = htons((short)device->eth_params->my_portd); + printf("[%s] binding to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"),eth->ehd.ether_shost[0],eth->ehd.ether_shost[1],eth->ehd.ether_shost[2],eth->ehd.ether_shost[3],eth->ehd.ether_shost[4],eth->ehd.ether_shost[5]); return 0; @@ -216,8 +205,6 @@ int trx_eth_write_raw_IF4p5(openair0_device *device, openair0_timestamp timestam packet_size = RAW_IF4p5_PULFFT_SIZE_BYTES(nblocks); } else if (flags == IF4p5_PULTICK) { packet_size = RAW_IF4p5_PULTICK_SIZE_BYTES; - } else if (flags == IF5_MOBIPASS) { - packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES; } else { packet_size = RAW_IF4p5_PRACH_SIZE_BYTES; } @@ -430,53 +417,6 @@ int trx_eth_read_raw_IF4p5(openair0_device *device, openair0_timestamp *timestam } -int trx_eth_read_raw_IF5_mobipass(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { - // Read nblocks info from packet itself - - int bytes_received=0; - eth_state_t *eth = (eth_state_t*)device->priv; - int ret; - - ssize_t packet_size = 28; //MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t ; -// ssize_t packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t); - - bytes_received = recv(eth->sockfdd, - buff[0], - packet_size, - MSG_PEEK); - - if (bytes_received ==-1) { - eth->num_rx_errors++; - perror("[MOBIPASS]ETHERNET IF5 READ (header): "); - exit(-1); - } - - IF5_mobipass_header_t *test_header = (IF5_mobipass_header_t*)((uint8_t *)buff[0] + MAC_HEADER_SIZE_BYTES); - *timestamp = test_header->time_stamp; - packet_size = MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 640*sizeof(int16_t); - - while(bytes_received < packet_size) { - ret = recv(eth->sockfdd, - buff[0], - packet_size, - 0); - if (bytes_received ==-1) { - eth->num_rx_errors++; - perror("[MOBIPASS] ETHERNET IF5 READ (payload): "); - return(-1); - } else { - bytes_received+=ret; - eth->rx_actual_nsamps = bytes_received>>1; - eth->rx_count++; - } - } - - eth->rx_nsamps = nsamps; - return(bytes_received); - - -} - int eth_set_dev_conf_raw(openair0_device *device) { eth_state_t *eth = (eth_state_t*)device->priv; diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c index 473d129aaf..2dfb4a7bf1 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c @@ -47,7 +47,7 @@ #include "ethernet_lib.h" #include "common/ran_context.h" -#define DEBUG 0 +//#define DEBUG 1 // These are for IF5 and must be put into the device structure if multiple RUs in the same RAU !!!!!!!!!!!!!!!!! uint16_t pck_seq_num = 1; @@ -142,8 +142,8 @@ int eth_socket_init_udp(openair0_device *device) { perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (control)"); exit(0); } - if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { - perror("ETHERNET: Cannot set SO_REUSEADDR option on socket (user)"); + if (setsockopt(eth->sockfdd, SOL_SOCKET, SO_NO_CHECK, &enable, sizeof(int))) { + perror("ETHERNET: Cannot set SO_NO_CHECK option on socket (user)"); exit(0); } @@ -202,8 +202,9 @@ int trx_eth_read_udp_IF4p5(openair0_device *device, openair0_timestamp *timestam goto again; } } else { - perror("ETHERNET IF4p5 READ"); - printf("(%s):\n", strerror(errno)); + return(-1); + //perror("ETHERNET IF4p5 READ"); + //printf("(%s):\n", strerror(errno)); } } else { *timestamp = test_header->sub_type; @@ -264,36 +265,82 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam return (bytes_sent); } -int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) { +int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags) { int bytes_sent=0; eth_state_t *eth = (eth_state_t*)device->priv; int sendto_flag =0; - int i=0; + //sendto_flag|=flags; eth->tx_nsamps=nsamps; - for (i=0;i>3; + __m256i buff_tx[nsamps2+1]; + __m256i *buff_tx2=buff_tx+1; +#else + nsamps2 = (nsamps+3)>>2; + __m128i buff_tx[nsamps2+2]; + __m128i *buff_tx2=buff_tx+2; +#endif +#elif defined(__arm__) || defined(__aarch64__) + nsamps2 = (nsamps+3)>>2; + int16x8_t buff_tx[nsamps2+2]; + int16x8_t *buff_tx2=buff_tx+2; +#else +#error Unsupported CPU architecture, ethernet device cannot be built +#endif + + + // bring TX data into 12 LSBs for softmodem RX + for (int j=0; jpck_header.seq_num = pck_seq_num; - //eth->pck_header.antenna_id = 1+(i<<1); - //eth->pck_header.timestamp = timestamp; - *(uint16_t *)buff2 = eth->pck_seq_num; - *(uint16_t *)(buff2 + sizeof(uint16_t)) = 1+(i<<1); - *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = timestamp; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TX_SEQ_NUM, eth->pck_seq_num); + // ECPRI Protocol revision + reserved bits (1 byte) + *(uint8_t *)buff2 = ECPRIREV; + // ECPRI Message type (1 byte) + *(uint8_t *)(buff2 + 1) = 64; + // ECPRI Payload Size (2 bytes) + AssertFatal(nsamps<16381,"nsamps > 16381\n"); + *(uint8_t *)(buff2 + 2) = (nsamps<<2)>>8; + *(uint8_t *)(buff2 + 3) = (nsamps<<2)&0xff; + // ECPRI PC_ID (2 bytes) + *(uint16_t *)(buff2 + 4) = cc; + // OAI modified SEQ_ID (4 bytes) + *(uint64_t *)(buff2 + 6) = ((uint64_t )timestamp)*6; + + /* + printf("ECPRI TX (REV %x, MessType %d, Payload size %d, PC_ID %d, TS %llu\n", + *(uint8_t *)buff2, + *(uint8_t *)(buff2+1), + *(uint16_t *)(buff2+2), + *(uint16_t *)(buff2+4), + *(uint64_t *)(buff2+6)); + */ int sent_byte; if (eth->compression == ALAW_COMPRESS) { @@ -311,7 +358,7 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi bytes_sent); #endif /* Send packet */ - bytes_sent += sendto(eth->sockfdd, + bytes_sent = sendto(eth->sockfdd, buff2, sent_byte, sendto_flag, @@ -339,17 +386,13 @@ int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, voi } //} - /* tx buffer values restored */ - *(int32_t *)buff2 = temp0; - *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1; - } - return (bytes_sent-APP_HEADER_SIZE_BYTES)>>2; } +#define NOSHIFT 1 -int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { +int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc) { int bytes_received=0; eth_state_t *eth = (eth_state_t*)device->priv; @@ -357,105 +400,98 @@ int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, voi int rcvfrom_flag =0; int block_cnt=0; int again_cnt=0; - int i=0; + static int packet_cnt=0; + int payload_size = UDP_PACKET_SIZE_BYTES(nsamps); +#if defined(__x86_64__) || defined(__i386__) +#ifdef __AVX2__ + int nsamps2 = (payload_size>>5)+1; + __m256i temp_rx[nsamps2]; + char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES; +#else + int nsamps2 = (payload_size>>4)+1; + __m128i temp_rx[nsamps2]; + char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES; +#endif +#elif defined(__arm__) || defined(__aarch64__) + int nsamps2 = (payload_size>>4)+1 + int16x8_t temp_rx[nsamps2]; + char *temp_rx0 = ((char *)&temp_rx[1])-APP_HEADER_SIZE_BYTES; +#else +#error Unsupported CPU architecture device cannot be built + int nsamps2 = (payload_size>>2)+1; + int32_t temp_rx[payload_size>>2]; + char* *temp_rx0 = ((char *)&temp_rx[1]) - APP_HEADER_SIZE_BYTES; +#endif + eth->rx_nsamps=nsamps; - for (i=0;icompression == ALAW_COMPRESS) { - receive_bytes = UDP_PACKET_SIZE_BYTES_ALAW(nsamps); - } else { - receive_bytes = UDP_PACKET_SIZE_BYTES(nsamps); - } - - while(bytes_received < receive_bytes) { - again: -#if DEBUG - printf("------- RX------: buff2 current position=%d remaining_bytes=%d bytes_recv=%d \n", - (void *)(buff2+bytes_received), - receive_bytes - bytes_received, - bytes_received); -#endif - bytes_received +=recvfrom(eth->sockfdd, - buff2, - receive_bytes, - rcvfrom_flag, - (struct sockaddr *)ð->dest_addrd, - (socklen_t *)ð->addr_len); - - if (bytes_received ==-1) { - eth->num_rx_errors++; - if (errno == EAGAIN) { - again_cnt++; - usleep(10); - if (again_cnt == 1000) { + bytes_received=0; + block_cnt=0; + AssertFatal(eth->compression == NO_COMPRESS, "IF5 compression not supported for now\n"); + + while(bytes_received < payload_size) { + again: + bytes_received +=recvfrom(eth->sockfdd, + temp_rx0, + payload_size, + rcvfrom_flag, + (struct sockaddr *)ð->dest_addrd, + (socklen_t *)ð->addr_len); + packet_cnt++; + if (bytes_received ==-1) { + eth->num_rx_errors++; + if (errno == EAGAIN) { + again_cnt++; + usleep(10); + if (again_cnt == 1000) { perror("ETHERNET READ: "); exit(-1); - } else { - printf("AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN AGAIN \n"); - goto again; - } - } else if (errno == EWOULDBLOCK) { - block_cnt++; - usleep(10); - if (block_cnt == 1000) { - perror("ETHERNET READ: "); - exit(-1); - } else { - printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); - goto again; - } + } else { + bytes_received=0; + goto again; + } + } else if (errno == EWOULDBLOCK) { + block_cnt++; + usleep(10); + if (block_cnt == 1000) { + perror("ETHERNET READ: "); + exit(-1); + } else { + printf("BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK BLOCK \n"); + goto again; } - } else { -#if DEBUG - printf("------- RX------: nu=%d an_id=%d ts%d bytes_recv=%d\n", - *(int16_t *)buff2, - *(int16_t *)(buff2 + sizeof(int16_t)), - *(openair0_timestamp *)(buff2 + sizeof(int32_t)), - bytes_received); - - dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, UDP_PACKET_SIZE_BYTES(nsamps),RX_FLAG); -#endif - - /* store the timestamp value from packet's header */ - *timestamp = *(openair0_timestamp *)(buff2 + sizeof(int32_t)); - /* store the sequence number of the previous packet received */ - if (eth->pck_seq_num_cur == 0) { - eth->pck_seq_num_prev = *(uint16_t *)buff2; - } else { - eth->pck_seq_num_prev = eth->pck_seq_num_cur; - } - /* get the packet sequence number from packet's header */ - eth->pck_seq_num_cur = *(uint16_t *)buff2; - if ( ( eth->pck_seq_num_cur != (eth->pck_seq_num_prev + 1) ) && !((eth->pck_seq_num_prev==MAX_PACKET_SEQ_NUM(nsamps,device->openair0_cfg->samples_per_frame)) && (eth->pck_seq_num_cur==1 )) && !((eth->pck_seq_num_prev==1) && (eth->pck_seq_num_cur==1))) { - //#if DEBUG - printf("Out of order packet received: current_packet=%d previous_packet=%d timestamp=%"PRId64"\n",eth->pck_seq_num_cur,eth->pck_seq_num_prev,*timestamp); - //#endif - } - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM,eth->pck_seq_num_cur); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RX_SEQ_NUM_PRV,eth->pck_seq_num_prev); - eth->rx_actual_nsamps=bytes_received>>2; - eth->rx_count++; - } - } - /* tx buffer values restored */ - *(int32_t *)buff2 = temp0; - *(openair0_timestamp *)(buff2 + sizeof(int32_t)) = temp1; - - } - return (bytes_received-APP_HEADER_SIZE_BYTES)>>2; + } else { + /* store the timestamp value from packet's header */ + *timestamp = *(openair0_timestamp *)(temp_rx0 + ECPRICOMMON_BYTES+ECPRIPCID_BYTES); + // convert TS to samples, /3 for 30.72 Ms/s, /6 for 15.36 Ms/s, /12 for 7.68 Ms/s, etc. + *timestamp = *timestamp/6; + // handle 1.4,3,5,10,15 MHz cases + *cc = *(uint16_t*)(temp_rx0 + ECPRICOMMON_BYTES); + } + eth->rx_actual_nsamps=payload_size>>2; + eth->rx_count++; + } + +#ifdef NOSHIFT + memcpy(buff,(void*)(temp_rx+1),payload_size); +#else + // populate receive buffer in lower 12-bits from 16-bit representation + for (int j=1; j>2); } diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index 1d3c280f0e..dce410de47 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -52,11 +52,20 @@ int num_devices_eth = 0; struct sockaddr_in dest_addr[MAX_INST]; int dest_addr_len[MAX_INST]; +int load_lib(openair0_device *device, + openair0_config_t *openair0_cfg, + eth_params_t *cfg, + uint8_t flag); int trx_eth_start(openair0_device *device) { eth_state_t *eth = (eth_state_t*)device->priv; + if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) { + AssertFatal(device->thirdparty_init != NULL, "device->thirdparty_init is null\n"); + AssertFatal(device->thirdparty_init(device) == 0, "third-party init failed\n"); + device->openair0_cfg->samples_per_packet = 256; + } /* initialize socket */ if (eth->flags == ETH_RAW_MODE) { printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n"); @@ -121,11 +130,6 @@ int trx_eth_start(openair0_device *device) - } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - printf("Setting ETHERNET to RAW_IF5_MODE\n"); - if (eth_socket_init_raw(device)!=0) return -1; - if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; - } else { printf("Setting ETHERNET to UDP_IF5_MODE\n"); if (eth_socket_init_udp(device)!=0) return -1; @@ -137,8 +141,7 @@ int trx_eth_start(openair0_device *device) if(eth_get_dev_conf_udp(device)!=0) return -1; }*/ - /* adjust MTU wrt number of samples per packet */ - if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; + //if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1; if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1; } @@ -166,9 +169,15 @@ void trx_eth_end(openair0_device *device) } -int trx_eth_stop(openair0_device *device) -{ - return(0); + +int trx_eth_stop(openair0_device *device) { + eth_state_t *eth = (eth_state_t*)device->priv; + + if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) { + AssertFatal(device->thirdparty_cleanup != NULL, "device->thirdparty_cleanup is null\n"); + AssertFatal(device->thirdparty_cleanup(device) == 0, "third-party cleanup failed\n"); + } + return(0); } @@ -387,20 +396,11 @@ int transport_init(openair0_device *device, eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t)); memset(eth, 0, sizeof(eth_state_t)); - if (eth_params->transp_preference == 1) { - eth->flags = ETH_RAW_MODE; - } else if (eth_params->transp_preference == 0) { - eth->flags = ETH_UDP_MODE; - } else if (eth_params->transp_preference == 3) { - eth->flags = ETH_RAW_IF4p5_MODE; - } else if (eth_params->transp_preference == 2) { - eth->flags = ETH_UDP_IF4p5_MODE; - } else if (eth_params->transp_preference == 4) { - eth->flags = ETH_RAW_IF5_MOBIPASS; - } else { - printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference); - eth->flags = ETH_RAW_MODE; - } + eth->flags = eth_params->transp_preference; + + // load third-party driver + if (eth->flags == ETH_UDP_IF5_ECPRI_MODE) load_lib(device,openair0_cfg,eth_params,RAU_REMOTE_THIRDPARTY_RADIO_HEAD); + if (eth_params->if_compress == 0) { eth->compression = NO_COMPRESS; @@ -423,12 +423,17 @@ int transport_init(openair0_device *device, device->trx_set_gains_func = trx_eth_set_gains; device->trx_write_init = trx_eth_write_init; - if (eth->flags == ETH_RAW_MODE) { + device->trx_read_func2 = NULL; + device->trx_read_func = NULL; + device->trx_write_func2 = NULL; + device->trx_write_func = NULL; + + if (eth->flags == ETH_RAW_MODE) { device->trx_write_func = trx_eth_write_raw; device->trx_read_func = trx_eth_read_raw; - } else if (eth->flags == ETH_UDP_MODE) { - device->trx_write_func = trx_eth_write_udp; - device->trx_read_func = trx_eth_read_udp; + } else if (eth->flags == ETH_UDP_MODE || eth->flags == ETH_UDP_IF5_ECPRI_MODE) { + device->trx_write_func2 = trx_eth_write_udp; + device->trx_read_func2 = trx_eth_read_udp; device->trx_ctlsend_func = trx_eth_ctlsend_udp; device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; } else if (eth->flags == ETH_RAW_IF4p5_MODE) { @@ -439,9 +444,6 @@ int transport_init(openair0_device *device, device->trx_read_func = trx_eth_read_udp_IF4p5; device->trx_ctlsend_func = trx_eth_ctlsend_udp; device->trx_ctlrecv_func = trx_eth_ctlrecv_udp; - } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) { - device->trx_write_func = trx_eth_write_raw_IF4p5; - device->trx_read_func = trx_eth_read_raw_IF5_mobipass; } else { //device->trx_write_func = trx_eth_write_udp_IF4p5; //device->trx_read_func = trx_eth_read_udp_IF4p5; diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h index 65b2def60d..ad64ac1a8a 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h @@ -49,7 +49,10 @@ #define RX_FLAG 0 #include "if_defs.h" -#define APP_HEADER_SIZE_BYTES (sizeof(int32_t) + sizeof(openair0_timestamp)) +#define ECPRICOMMON_BYTES 4 +#define ECPRIPCID_BYTES 2 +#define APP_HEADER_SIZE_BYTES (ECPRICOMMON_BYTES + ECPRIPCID_BYTES + sizeof(openair0_timestamp)) +#define ECPRIREV 1 // ECPRI Version 1, C=0 - single ECPRI message per OAI TX packet /*!\brief opaque ethernet data structure */ typedef struct { @@ -234,8 +237,8 @@ int ethernet_tune(openair0_device *device, unsigned int option, int value); * @ingroup _oai */ int eth_socket_init_udp(openair0_device *device); -int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags); -int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc); +int trx_eth_write_udp(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int cc, int flags); +int trx_eth_read_udp(openair0_device *device, openair0_timestamp *timestamp, void *buff, int nsamps, int *cc); int eth_socket_init_raw(openair0_device *device); diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h index 0f2147847a..47205cf8b8 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h @@ -36,15 +36,17 @@ #include #include +#ifndef LITE_COMPILATION #include "PHY/LTE_TRANSPORT/if4_tools.h" #include "PHY/LTE_TRANSPORT/if5_tools.h" +#endif // ETH transport preference modes -#define ETH_UDP_MODE 0 -#define ETH_RAW_MODE 1 +#define ETH_UDP_MODE 0 +#define ETH_RAW_MODE 1 #define ETH_UDP_IF4p5_MODE 2 #define ETH_RAW_IF4p5_MODE 3 -#define ETH_RAW_IF5_MOBIPASS 4 +#define ETH_UDP_IF5_ECPRI_MODE 4 // COMMOM HEADER LENGTHS diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c index 37f55c689f..76855111e1 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -207,7 +207,7 @@ next: uint16_t *in; uint16_t *out; in = (uint16_t *)s->buffers.prach[*subframe]; - out = (uint16_t *)ru->prach_rxsigF[antenna]; + out = (uint16_t *)ru->prach_rxsigF[0][antenna]; for (i = 0; i < 840*2; i++) out[i] = ntohs(in[i]); s->buffers.prach_busy[*subframe] = 0; diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c index 9b64f01d44..42953d1d4a 100644 --- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -86,10 +86,9 @@ static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; static struct rte_eth_conf port_conf = { .rxmode = { .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_CRC_STRIP, - .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, - .split_hdr_size = 0, - .max_rx_pkt_len = 9500, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, + .split_hdr_size = 0, + .max_rx_pkt_len = 9500, }, .txmode = { .mq_mode = ETH_MQ_TX_NONE, diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c index c1ae1afcc7..2f60e7dc49 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -215,7 +215,7 @@ next: uint16_t *in; uint16_t *out; in = (uint16_t *)s->buffers.prach[*slot]; - out = (uint16_t *)ru->prach_rxsigF[antenna]; + out = (uint16_t *)ru->prach_rxsigF[0][antenna]; for (i = 0; i < 839*2; i++) out[i] = ntohs(in[i]); s->buffers.prach_busy[*slot] = 0; @@ -275,6 +275,7 @@ void benetel_fh_if4p5_south_out(RU_t *ru, int slot, uint64_t timestamp) { + //printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp); benetel_eth_state_t *s = ru->ifdevice.priv; NR_DL_FRAME_PARMS *fp; diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c index b90702d331..dd50603ec5 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -86,10 +86,9 @@ static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; static struct rte_eth_conf port_conf = { .rxmode = { .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_CRC_STRIP, - .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, - .split_hdr_size = 0, - .max_rx_pkt_len = 9500, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, + .split_hdr_size = 0, + .max_rx_pkt_len = 9500, }, .txmode = { .mq_mode = ETH_MQ_TX_NONE, @@ -234,7 +233,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) } // Trigger start send DL packets - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && SYMBOL == 0x46 && ANT_NUM == 0x00 && SUBFRAME == 0x00 && dl_start == 0){ + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && SYMBOL == 0x44 && ANT_NUM == 0x00 && SUBFRAME == 0x00 && dl_start == 0){ printf("\nU-Plane Started\n"); printf("\n====================================================\n"); @@ -253,7 +252,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) p.antenna = 0; memcpy(p.iq, IQ_ptr, 5088); store_ul(bs, &p); - //if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); + // if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); } // U-PLANE UL ANT_0 PROCESSING @@ -268,7 +267,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) int tx_frame = frame; int tx_subframe = subframe; int tx_slot = slot; - int tx_symbol = symbol + 8; + int tx_symbol = symbol + 10; if (tx_symbol > 13) { tx_symbol -= 14; @@ -286,7 +285,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) ANT_NUM = 0x00; // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) + 8) % 14; + SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14; ANT_NUM = 0x00; SUBFRAME = sf; @@ -307,6 +306,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, 1272*4); } +//printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf); bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol); unlock_dl_buffer(bs->buffers, oai_slot); @@ -319,7 +319,7 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) { // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) + 8) % 14; + SYMBOL = ((SYMBOL & 0b00111111) +10) % 14; ANT_NUM = 0x01; SUBFRAME = sf; @@ -348,10 +348,10 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){ if (ANT_NUM == 0) { int subframe = SUBFRAME >> 4; - int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); + //int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); if (subframe==9) { //printf("store prach f.sf.sl %d.%d.%d %d\n", FRAME, subframe, slot, subframe * 2 + slot); - store_prach(bs, FRAME, slot /*subframe * 2 + slot*/, IQ_ptr); + store_prach(bs, FRAME, subframe * 2 + 1, IQ_ptr); } } rte_pktmbuf_free(m); diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c index 984e401421..52c9f24127 100644 --- a/targets/ARCH/ETHERNET/benetel/5g/low.c +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -27,17 +27,50 @@ void store_ul(benetel_t *bs, ul_packet_t *ul) { +#if 0 +struct timespec t; +static struct timespec old; +clock_gettime(CLOCK_REALTIME, &t); +printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - old.tv_nsec); +old = t; +#endif + /* only antenna 0 for the moment */ if (ul->antenna != 0) return; if (ul->slot != bs->next_slot || ul->symbol != bs->next_symbol) { - printf("%s: fatal, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", __FUNCTION__, bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, ul->frame, ul->slot, ul->symbol); - exit(1); + } + + /* fill missing data with 0s */ + while (ul->slot != bs->next_slot || + ul->symbol != bs->next_symbol) { + lock_ul_buffer(bs->buffers, bs->next_slot); + if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { + printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + bs->next_slot, bs->next_symbol); + } + + memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + 0, 1272*4); + bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); + signal_ul_buffer(bs->buffers, bs->next_slot); + unlock_ul_buffer(bs->buffers, bs->next_slot); + + bs->next_symbol++; + if (bs->next_symbol == 14) { + bs->next_symbol = 0; + bs->next_slot = (bs->next_slot + 1) % 20; + if (bs->next_slot == 0) { + bs->expected_benetel_frame++; + bs->expected_benetel_frame &= 255; + } + } } lock_ul_buffer(bs->buffers, bs->next_slot); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 0c89a68dd5..dd29d01fae 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -69,7 +69,7 @@ /** @addtogroup _USRP_PHY_RF_INTERFACE_ * @{ */ - +int gpio789=0; extern int usrp_tx_thread; @@ -692,6 +692,12 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; + // push GPIO bits 7-9 from flags_msb + /*s->usrp->set_command_time(uhd::time_spec_t::from_ticks((s->rx_timestamp+(2*nsamps)),s->sample_rate)); + s->usrp->set_gpio_attr("FP0", "OUT", gpio789<<7, 0x380); + s->usrp->clear_command_time(); + gpio789 = (gpio789+1)&7;*/ + if (device->recplay_state != NULL) { // record mode // Copy subframes to memory (later dump on a file) if (device->recplay_state->nb_samples < device->openair0_cfg->recplay_conf->u_sf_max) { diff --git a/targets/ARCH/rfsimulator/README.md b/targets/ARCH/rfsimulator/README.md index 9ec0ae5065..4a8d5ff79a 100644 --- a/targets/ARCH/rfsimulator/README.md +++ b/targets/ARCH/rfsimulator/README.md @@ -59,6 +59,29 @@ The RF simulator is using the configuration module, and its parameters are defin Setting the env variable RFSIMULATOR can be used instead of using the serveraddr parameter; it is to preserve compatibility with previous version. +## How to use the RF simulator options + +Add the following options to the command line to enable the channel model and the IQ samples saving for future replay: +```bash +--rfsimulator.options chanmod,saviq +``` +or just: +```bash +--rfsimulator.options chanmod +``` +to enable the channel model. + +set the model with: +```bash +--rfsimulator.modelname AWGN +``` + +Example run: + +```bash +sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD --rfsim --phy-test --rfsimulator.options chanmod --rfsimulator.modelname AWGN +``` + ## 4G case For the UE, it should be set to the IP address of the eNB. For example: @@ -165,5 +188,50 @@ Only the input noise can be changed on command line with the `-s` parameter. With path loss = 0 set `-s 5` to see a little noise. `-s` is a shortcut to `channelmod.s`. It is expected to enhance the channel modelization flexibility by the addition of more parameters in the channelmod section. +Example to add a very small noise: +```bash +-s 30 +``` +to add a lot of noise: +```bash +-s 5 +``` + +Example run commands: +```bash +sudo RFSIMULATOR=server ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD --rfsim --phy-test --rfsimulator.options chanmod --rfsimulator.modelname AWGN + +``` +# Real time control and monitoring + +Add the `--telnetsrv` option to the command line. Then in a new shell, connect to the telnet server, example: +```bash +telnet 127.0.0.1 9090 +``` +once connected it is possible to monitor the current status: +```bash +channelmod show current +``` + +see the available channel models: +```bash +channelmod show predef +``` + +or modify the channel model, for example setting a new model: +```bash +rfsimu setmodel AWGN +``` +setting the pathloss, etc...: +```bash +channelmod modify +channelmod modify 0 ploss 15 +``` +where: +```bash + can be one of "riceanf", "aoa", "randaoa", "ploss", "offset", "forgetf" +``` + # Caveats Still issues in power control: txgain, rxgain are not used. + diff --git a/targets/ARCH/rfsimulator/apply_channelmod.c b/targets/ARCH/rfsimulator/apply_channelmod.c index 7aa5d78bf8..3f4c0e1517 100644 --- a/targets/ARCH/rfsimulator/apply_channelmod.c +++ b/targets/ARCH/rfsimulator/apply_channelmod.c @@ -102,8 +102,9 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si } //l } - out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); - out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); + // Fixme: lround(), rount(), ... is detected by valgrind as error, not found why + out_ptr->r += lround(rx_tmp.x*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); + out_ptr->i += lround(rx_tmp.y*pathLossLinear + noise_per_sample*gaussZiggurat(0.0,1.0)); out_ptr++; } diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 93c07a575f..79bf3dd077 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -91,13 +91,13 @@ extern RAN_CONTEXT_t RC; static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); static telnetshell_cmddef_t rfsimu_cmdarray[] = { - {"setmodel","",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, + {"setmodel","",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, {"","",NULL}, }; static telnetshell_vardef_t rfsimu_vardef[] = { {"",0,NULL} -}; +}; pthread_mutex_t Sockmutex; typedef struct complex16 sample_t; // 2*16 bits complex number @@ -170,11 +170,13 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { static bool init_done=false; if (!init_done) { - uint64_t rand; - FILE *h=fopen("/dev/random","r"); + uint64_t rand; + FILE *h=fopen("/dev/random","r"); + if ( 1 != fread(&rand,sizeof(rand),1,h) ) LOG_W(HW, "Simulator can't read /dev/random\n"); - fclose(h); + + fclose(h); randominit(rand); tableNor(rand); init_done=true; @@ -189,7 +191,6 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->chan_offset, // maybe used for TA bridge->chan_pathloss); // path_loss in dB set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID); - random_channel(ptr->channel_model,false); } } @@ -317,25 +318,29 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { } static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { - char *modelname=NULL; + char *modelname=NULL; int s = sscanf(buff,"%ms\n",&modelname); + if (s == 1) { int channelmod=modelid_fromname(modelname); + if (channelmod<0) prnt("ERROR: model %s unknown\n",modelname); else { - rfsimulator_state_t *t = (rfsimulator_state_t *)arg; - for (int i=0; ibuf[i]; + if (b->conn_sock >= 0 ) { channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels, - channelmod, - t->sample_rate, - t->tx_bw, - 30e-9, // TDL delay-spread parameter - t->chan_forgetfact, // forgetting_factor - t->chan_offset, // maybe used for TA - t->chan_pathloss); // path_loss in dB + channelmod, + t->sample_rate, + t->tx_bw, + 30e-9, // TDL delay-spread parameter + t->chan_forgetfact, // forgetting_factor + t->chan_offset, // maybe used for TA + t->chan_pathloss); // path_loss in dB set_channeldesc_owner(newmodel, RFSIMU_MODULEID); random_channel(newmodel,false); channel_desc_t *oldmodel=b->channel_model; @@ -346,8 +351,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, } } } else { - prnt("ERROR: no model specified\n"); + prnt("ERROR: no model specified\n"); } + free(modelname); return CMDSTATUS_FOUND; } @@ -368,7 +374,7 @@ sin_addr: }; bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr)); AssertFatal(listen(t->listen_sock, 5) == 0, ""); - struct epoll_event ev={0}; + struct epoll_event ev= {0}; ev.events = EPOLLIN; ev.data.fd = t->listen_sock; AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, ""); @@ -440,7 +446,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp if (t->lastWroteTS > timestamp+nsamps) LOG_E(HW,"Not supported to send Tx out of order (same in USRP) %lu, %lu\n", - t->lastWroteTS, timestamp); + t->lastWroteTS, timestamp); t->lastWroteTS=timestamp+nsamps; @@ -505,9 +511,9 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi if ( b->headerMode) blockSz=b->remainToTransfer; else - blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ? + blockSz= b->transferPtr + b->remainToTransfer <= b->circularBufEnd ? b->remainToTransfer : - b->circularBufEnd - 1 - b->transferPtr ; + b->circularBufEnd - b->transferPtr ; ssize_t sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT); @@ -523,7 +529,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi AssertFatal((b->remainToTransfer-=sz) >= 0, ""); b->transferPtr+=sz; - if (b->transferPtr==b->circularBufEnd - 1) + if (b->transferPtr==b->circularBufEnd ) b->transferPtr=(char *)b->circularBuf; // check the header and start block transfer @@ -533,33 +539,32 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi b->headerMode=false; if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS - t->nextTimestamp=b->th.timestamp> nsamps_for_initial ? - b->th.timestamp - nsamps_for_initial : - 0; - b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ? - b->th.timestamp : - nsamps_for_initial; - LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp); - b->trashingPacket=true; - } else if ( b->lastReceivedTS < b->th.timestamp) { + t->nextTimestamp=b->th.timestamp> nsamps_for_initial ? + b->th.timestamp - nsamps_for_initial : + 0; + b->lastReceivedTS=b->th.timestamp> nsamps_for_initial ? + b->th.timestamp : + nsamps_for_initial; + LOG_W(HW,"UE got first timestamp: starting at %lu\n", t->nextTimestamp); + b->trashingPacket=true; + } else if ( b->lastReceivedTS < b->th.timestamp) { int nbAnt= b->th.nbAnt; if ( b->th.timestamp-b->lastReceivedTS < CirSize ) { - for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { - for (int a=0; a < nbAnt; a++) { - b->circularBuf[(index*nbAnt+a)%CirSize].r = 0; - b->circularBuf[(index*nbAnt+a)%CirSize].i = 0; + for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { + for (int a=0; a < nbAnt; a++) { + b->circularBuf[(index*nbAnt+a)%CirSize].r = 0; + b->circularBuf[(index*nbAnt+a)%CirSize].i = 0; + } } - } } else { - memset(b->circularBuf, 0, sampleToByte(CirSize,1)); - } + memset(b->circularBuf, 0, sampleToByte(CirSize,1)); + } - if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS > 50 ) + if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS < 1000) LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS ); b->lastReceivedTS=b->th.timestamp; - } else if ( b->lastReceivedTS > b->th.timestamp && b->th.size == 1 ) { LOG_W(HW,"Received Rx/Tx synchro out of order\n"); b->trashingPacket=true; @@ -567,7 +572,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi // normal case } else { LOG_E(HW, "received data in past: current is %lu, new reception: %lu!\n", b->lastReceivedTS, b->th.timestamp); - b->trashingPacket=true; + b->trashingPacket=true; } pthread_mutex_lock(&Sockmutex); @@ -628,7 +633,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo t->nextTimestamp+=nsamps; if ( ((t->nextTimestamp/nsamps)%100) == 0) - LOG_W(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextTimestamp); + LOG_D(HW,"No UE, Generated void samples for Rx: %ld\n", t->nextTimestamp); *ptimestamp = t->nextTimestamp-nsamps; return nsamps; @@ -646,27 +651,27 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo // We can never write is the past from the received time // So, the node perform receive but will never write these symbols // let's tell this to the opposite node - // We send timestamp for nb samples required - // assuming this should have been done earlier if a Tx would exist + // We send timestamp for nb samples required + // assuming this should have been done earlier if a Tx would exist pthread_mutex_unlock(&Sockmutex); struct complex16 v= {0}; - void *samplesVoid[t->tx_num_channels]; + void *dummyS[t->tx_num_channels]; for ( int i=0; i < t->tx_num_channels; i++) - samplesVoid[i]=(void *)&v; + dummyS[i]=(void *)&v; - LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n", - t->lastWroteTS, t->nextTimestamp); + LOG_I(HW, "No samples Tx occured, so we send 1 sample to notify it: Tx:%lu, Rx:%lu\n", + t->lastWroteTS, t->nextTimestamp); rfsimulator_write_internal(t, t->nextTimestamp, - samplesVoid, 1, + dummyS, 1, t->tx_num_channels, 1, true); } else { - pthread_mutex_unlock(&Sockmutex); + pthread_mutex_unlock(&Sockmutex); LOG_W(HW, "trx_write came from another thread\n"); } } else pthread_mutex_unlock(&Sockmutex); - + bool have_to_wait; do { @@ -706,8 +711,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo // it seems legacy behavior is: never in UL, each frame in DL if (reGenerateChannel) random_channel(ptr->channel_model,0); + if (t->poll_telnetcmdq) - t->poll_telnetcmdq(t->telnetcmd_qid,t); + t->poll_telnetcmdq(t->telnetcmd_qid,t); for (int a=0; achannel_model != NULL ) // apply a channel model @@ -721,12 +727,13 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo else { // no channel modeling sample_t *out=(sample_t *)samplesVoid[a]; int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas + //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx); for (int i=0; i < nsamps; i++) {//loop over nsamps - for (int a_tx=0; a_txcircularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r; - out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i; - } // end for a_tx + for (int a_tx=0; a_txcircularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r; + out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i; + } // end for a_tx } // end for i (number of samps) } // end of no channel modeling } // end for a (number of rx antennas) @@ -765,7 +772,7 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { return 0; } -int rfsimulator_write_init(openair0_device *device){ +int rfsimulator_write_init(openair0_device *device) { return 0; } __attribute__((__visibility__("default"))) @@ -804,18 +811,20 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator->tx_bw=openair0_cfg->tx_bw; //randominit(0); set_taus_seed(0); - /* look for telnet server, if it is loaded, add the channel modeling commands to it */ + /* 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) { - rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME); + rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME); addcmd("rfsimu",rfsimu_vardef,rfsimu_cmdarray); + for(int i=0; rfsimu_cmdarray[i].cmdfunc != NULL; i++) { - if ( rfsimu_cmdarray[i].qptr != NULL) { + if ( rfsimu_cmdarray[i].qptr != NULL) { rfsimulator->telnetcmd_qid = rfsimu_cmdarray[i].qptr; break; } - } - } + } + } + return 0; } diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index 73f6321ffe..daf0133af2 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -34,7 +34,8 @@ int fullread(int fd, void *_buf, int count) { while (count) { l = read(fd, buf, count); - if (l <= 0) return -1; + if (l <= 0) + return -1; count -= l; buf += l; @@ -43,6 +44,44 @@ int fullread(int fd, void *_buf, int count) { return ret; } +#define shift 4 +int32_t signal_energy(int32_t *input,uint32_t length) { + int32_t i; + int32_t temp,temp2; + register __m64 mm0,mm1,mm2,mm3; + __m64 *in = (__m64 *)input; + mm0 = _mm_setzero_si64();//pxor(mm0,mm0); + mm3 = _mm_setzero_si64();//pxor(mm3,mm3); + + for (i=0; i>1; i++) { + mm1 = in[i]; + mm2 = mm1; + mm1 = _m_pmaddwd(mm1,mm1); + mm1 = _m_psradi(mm1,shift);// shift any 32 bits blocs of the word by the value shift + mm0 = _m_paddd(mm0,mm1);// add the two 64 bits words 4 bytes by 4 bytes + // mm2 = _m_psrawi(mm2,shift_DC); + mm3 = _m_paddw(mm3,mm2);// add the two 64 bits words 2 bytes by 2 bytes + } + + mm1 = mm0; + mm0 = _m_psrlqi(mm0,32); + mm0 = _m_paddd(mm0,mm1); + temp = _m_to_int(mm0); + temp/=length; + temp<<=shift; // this is the average of x^2 + // now remove the DC component + mm2 = _m_psrlqi(mm3,32); + mm2 = _m_paddw(mm2,mm3); + mm2 = _m_pmaddwd(mm2,mm2); + temp2 = _m_to_int(mm2); + temp2/=(length*length); + // temp2<<=(2*shift_DC); + temp -= temp2; + _mm_empty(); + _m_empty(); + return((temp>0)?temp:1); +} + void fullwrite(int fd, void *_buf, int count) { char *buf = _buf; @@ -131,8 +170,8 @@ void setblocking(int sock, enum blocking_t active) { } int main(int argc, char *argv[]) { - if(argc != 4) { - printf("Need parameters: source file, server or destination IP, TCP port\n"); + if(argc < 4) { + printf("Need parameters: source file, server or destination IP, TCP port (4043), 'UL|DL' if raw 2*16bits format: UL for UL IQ, DL for DL IQs \n"); exit(1); } @@ -147,10 +186,21 @@ int main(int argc, char *argv[]) { serviceSock=client_start(argv[2],atoi(argv[3])); } + uint64_t typeStamp=ENB_MAGICDL_FDD; + boolean_t raw=false; + + if ( argc == 5 ) { + raw=true; + + if (strcmp(argv[4],"UL") == 0 ) + typeStamp=UE_MAGICDL_FDD; + } + samplesBlockHeader_t header; int bufSize=100000; void *buff=malloc(bufSize); - uint64_t readTS=0; + uint64_t timestamp=0; + const int blockSize=1000; while (1) { //Rewind the file to loop on the samples @@ -159,10 +209,21 @@ int main(int argc, char *argv[]) { // Read one block and send it setblocking(serviceSock, blocking); - AssertFatal(read(fd,&header,sizeof(header)), ""); + + if ( raw ) { + header.magic=typeStamp; + header.size=blockSize; + header.nbAnt=1; + header.timestamp=timestamp; + timestamp+=blockSize; + header.option_value=0; + header.option_flag=0; + } else { + AssertFatal(read(fd,&header,sizeof(header)), ""); + } + fullwrite(serviceSock, &header, sizeof(header)); int dataSize=sizeof(int32_t)*header.size*header.nbAnt; - uint64_t wroteTS=header.timestamp; if (dataSize>bufSize) { void *new_buff = realloc(buff, dataSize); @@ -176,21 +237,28 @@ int main(int argc, char *argv[]) { } AssertFatal(read(fd,buff,dataSize) == dataSize, ""); + + if (raw) // UHD shifts the 12 ADC values in MSB + for (int i=0; i 0 ) ; } return 0; diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c deleted file mode 100644 index 13f72b3876..0000000000 --- a/targets/COMMON/create_nr_tasks.c +++ /dev/null @@ -1,111 +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 - */ - - -# include "intertask_interface.h" -# include "create_nr_tasks.h" -# include "common/utils/LOG/log.h" - -# ifdef OPENAIR2 -#include "sctp_eNB_task.h" -#include "s1ap_eNB.h" -#include "nas_ue_task.h" -#include "udp_eNB_task.h" -#include "gtpv1u_eNB_task.h" -# if ENABLE_RAL -# include "lteRALue.h" -# include "lteRALenb.h" -# endif -#include "RRC/NR/nr_rrc_defs.h" -# endif -# include "gnb_app.h" - -extern int emulate_rf; - -int create_gNB_tasks(uint32_t gnb_nb) -{ - LOG_D(GNB_APP, "%s(gnb_nb:%d\n", __FUNCTION__, gnb_nb); - - itti_wait_ready(1); - if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) { - LOG_E(PDCP, "Create task for L2L1 failed\n"); - return -1; - } - - if (gnb_nb > 0) { - // Last task to create, others task must be ready before its start - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - } - } - - - if (EPC_MODE_ENABLED) { - if (gnb_nb > 0) { - /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; - } - - if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for S1AP failed\n"); - return -1; - }*/ - if(!emulate_rf){ - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; - } - } - - if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) { - LOG_E(GTPU, "Create task for GTPV1U failed\n"); - return -1; - } - } - - } - - /*if (gnb_nb > 0) { - // Last task to create, others task must be ready before its start - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - } - }*/ - - - if (gnb_nb > 0) { - LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); - - if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); - return -1; - } - } - - - itti_wait_ready(0); - - return 0; -} -//#endif diff --git a/targets/COMMON/create_nr_tasks.h b/targets/COMMON/create_nr_tasks.h index ca259a2b34..23dd23e7db 100644 --- a/targets/COMMON/create_nr_tasks.h +++ b/targets/COMMON/create_nr_tasks.h @@ -22,8 +22,6 @@ #ifndef CREATE_NR_TASKS_H_ #define CREATE_NR_TASKS_H_ -/* External declaration of L2L1 task that depend on the target */ -extern void *l2l1_task(void *arg); int create_gNB_tasks(uint32_t gnb_nb); diff --git a/targets/COMMON/create_tasks.h b/targets/COMMON/create_tasks.h index 843897cefb..e3f871964a 100644 --- a/targets/COMMON/create_tasks.h +++ b/targets/COMMON/create_tasks.h @@ -22,9 +22,6 @@ #ifndef CREATE_TASKS_H_ #define CREATE_TASKS_H_ -/* External declaration of L2L1 task that depend on the target */ -extern void *l2l1_task(void *arg); - int create_tasks(uint32_t enb_nb); int create_tasks_ue(uint32_t ue_nb); int create_tasks_mbms(uint32_t enb_nb); diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index aa99eee048..ad98a6091b 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -8,23 +8,11 @@ # define NUMBER_OF_NR_RU_MAX 2 # ifndef PHYSIM # ifndef UE_EXPANSION -// TODO:L2 FAPI simulator. -// UESIM_EXPANSION is used to be same value of NUMBER_OF_UE_MAX -// in eNB and UE. -// now , if we use --mu option in UE, compiling error will occur. -// This problem will be fixed in the future. -# ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 4 # define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_UCI_VARS_MAX 14 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 -# else -# define NUMBER_OF_UE_MAX 256 -# define NUMBER_OF_UCI_VARS_MAX 256 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -# define NUMBER_OF_CONNECTED_gNB_MAX 3 -# endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_UCI_VARS_MAX 256 @@ -32,7 +20,8 @@ # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif # else -# define NUMBER_OF_UE_MAX 1 +# define NUMBER_OF_UE_MAX 4 +# define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 @@ -48,17 +37,10 @@ eNB process will exit because unexpected access happens. Now some parts are using NUMBER_OF_UE_MAX and the other are using MAX_MOBILES_PER_ENB in for-loop. */ -# ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_UCI_VARS_MAX 56 # define NUMBER_OF_CONNECTED_eNB_MAX 3 # define NUMBER_OF_CONNECTED_gNB_MAX 3 -# else -# define NUMBER_OF_UE_MAX 256 -# define NUMBER_OF_UCI_VARS_MAX 256 -# define NUMBER_OF_CONNECTED_eNB_MAX 1 -# define NUMBER_OF_CONNECTED_gNB_MAX 3 -# endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_UCI_VARS_MAX 256 diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 0e3b9fffdf..49b4e4441e 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -139,6 +139,8 @@ eNBs = discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //SSB central frequency of NR secondary cell group (for ENDC NSA) + nr_scg_ssb_freq = 640000; } ); @@ -174,14 +176,14 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.61.195"; + mme_ip_address = ( { ipv4 = "192.168.18.99"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } ); - enable_measurement_reports = "no"; + enable_measurement_reports = "yes"; ///X2 enable_x2 = "yes"; @@ -193,9 +195,9 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.160.46"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.196"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.160.46"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.18.196"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -226,7 +228,7 @@ RUs = ( { //local_if_name = "enp129s0f0"; local_if_name = "dpdk"; - sdr_addrs = "softmodem -m 2048 -l 8 -n 2 -b 0000:3b:00.0 --proc-type auto --file-prefix ggg -- -p 0x1"; + sdr_addrs = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1"; #sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 5e02f16b02..037de199df 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; servingCellConfigCommon = ( { @@ -203,7 +205,7 @@ gNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.61.195"; + mme_ip_address = ( { ipv4 = "192.168.18.99"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -227,9 +229,9 @@ gNBs = { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.160.146/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.160.146/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 @@ -267,7 +269,7 @@ RUs = ( clock_src = "external"; local_if_name = "dpdk"; - sdr_addrs = "softmodem -m 2048 -l 6 -n 3 -b 0000:3b:00.1 --proc-type auto --file-prefix hhh -- -p 0x1"; + sdr_addrs = "softmodem -m 2048 -l 34 -n 3 -b 0000:81:00.2 --proc-type auto --file-prefix hhh -- -p 0x1"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; local_portc = 50000; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 983404e459..f2e468c71b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -71,6 +71,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 257; @@ -89,7 +94,7 @@ gNBs = initialULBWPsubcarrierSpacing = 3; #rach-ConfigCommon #rach-ConfigGeneric - prach_ConfigurationIndex = 98; + prach_ConfigurationIndex = 52; #prach_msg1_FDM #0 = one, 1=two, 2=four, 3=eight prach_msg1_FDM = 0; @@ -103,12 +108,12 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 7; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen +#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 7; #ra_ContentionResolutionTimer #(0..7) 8,16,24,32,40,48,56,64 ra_ContentionResolutionTimer = 7; @@ -119,22 +124,26 @@ gNBs = prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # - msg1_SubcarrierSpacing = 1, + msg1_SubcarrierSpacing = 3, # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 14; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -170,11 +179,11 @@ gNBs = # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 10; - nrofDownlinkSymbols = 0; - nrofUplinkSlots = 10; - nrofUplinkSymbols = 0; + dl_UL_TransmissionPeriodicity = 3; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; ssPBCH_BlockPower = 10; } @@ -238,7 +247,9 @@ RUs = ( max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; - if_freq = 5300000000; + if_freq = 5300000000L; + #time_source = "external"; + clock_source = "external"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index e171b2faa9..f810dd546c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -13,7 +13,7 @@ gNBs = gNB_name = "gNB-Eurecom-5GNRBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values - tracking_area_code = 600; + tracking_area_code = 1; plmn_list = ({mcc = 311; mnc = 480; mnc_length = 3;}); @@ -23,6 +23,8 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; servingCellConfigCommon = ( { @@ -45,7 +47,7 @@ gNBs = dl_carrierBandwidth = 32; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=50 (275*(L-1))+RBstart + # this is RBstart=0,L=32 (275*(L-1))+RBstart initialDLBWPlocationAndBandwidth = 8525; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 @@ -71,6 +73,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 261; @@ -89,7 +96,7 @@ gNBs = initialULBWPsubcarrierSpacing = 3; #rach-ConfigCommon #rach-ConfigGeneric - prach_ConfigurationIndex = 98; + prach_ConfigurationIndex = 52; #prach_msg1_FDM #0 = one, 1=two, 2=four, 3=eight prach_msg1_FDM = 0; @@ -103,38 +110,42 @@ gNBs = powerRampingStep = 1; #ra_ReponseWindow #1,2,4,8,10,20,40,80 - ra_ResponseWindow = 4; + ra_ResponseWindow = 7; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR #0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 - ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 7; #ra_ContentionResolutionTimer #(0..7) 8,16,24,32,40,48,56,64 ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # - msg1_SubcarrierSpacing = 1, + msg1_SubcarrierSpacing = 3, # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 2; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 14; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -148,7 +159,7 @@ gNBs = # ssb_PositionsInBurs_BitmapPR # 1=short, 2=medium, 3=long ssb_PositionsInBurst_PR = 3; - ssb_PositionsInBurst_Bitmap = 0x100000001L; + ssb_PositionsInBurst_Bitmap = 0x0001000100010001L; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 @@ -170,11 +181,11 @@ gNBs = # pattern1 # dl_UL_TransmissionPeriodicity # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 - dl_UL_TransmissionPeriodicity = 5; - nrofDownlinkSlots = 10; - nrofDownlinkSymbols = 0; - nrofUplinkSlots = 10; - nrofUplinkSymbols = 0; + dl_UL_TransmissionPeriodicity = 3; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; ssPBCH_BlockPower = 10; } @@ -192,21 +203,36 @@ gNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "192.168.18.99"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.18.199"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + NETWORK_INTERFACES : { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.198/24"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.198/24"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.18.198/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 }; } ); @@ -239,6 +265,8 @@ RUs = ( eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; if_freq = 5124520000L; + clock_src = "external"; + time_src = "external"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf new file mode 100644 index 0000000000..9e13d493a8 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -0,0 +1,284 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 433096; + dl_frequencyBand = 66; + # this is 2150 MHz + dl_absoluteFrequencyPointA = 430000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + ul_absoluteFrequencyPointA = 350000; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf new file mode 100644 index 0000000000..831f9c7978 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -0,0 +1,284 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 433096; + dl_frequencyBand = 66; + # this is 2150 MHz + dl_absoluteFrequencyPointA = 430000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 66; + ul_absoluteFrequencyPointA = 350000; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "type=x300"; + clock_src = "external"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 60acb20ecb..760689f653 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -23,7 +23,7 @@ gNBs = ssb_SubcarrierOffset = 0; pdsch_AntennaPorts = 1; - + servingCellConfigCommon = ( { #spCellConfigCommon @@ -45,7 +45,7 @@ gNBs = dl_carrierBandwidth = 106; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=50 (275*(L-1))+RBstart + # this is RBstart=41,L=24 (275*(L-1))+RBstart initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 @@ -74,7 +74,7 @@ gNBs = initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=1,L=4 + #this is SS=1,L=5 initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon @@ -135,18 +135,17 @@ gNBs = initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - - initialULBWPk2_1 = 6; + + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; - initialULBWPk2_2 = 7; + initialULBWPk2_2 = 7; initialULBWPmappingType_2 = 1; # this is SS=10 L=4 initialULBWPstartSymbolAndLength_2 = 52; - msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -234,6 +233,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); @@ -246,10 +246,17 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 75; + max_rxgain = 50; eNB_instances = [0]; - #beamforming 1x4 matrix: - bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + ##beamforming 1x2 matrix: 1 layer x 2 antennas + bf_weights = [0x00007fff, 0x0000]; + ##beamforming 1x4 matrix: 1 layer x 4 antennas + #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000]; + ## beamforming 2x2 matrix: + # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + ## beamforming 4x4 matrix: + #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index 0b04dc82d1..d38fff4241 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 13475; + initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -74,8 +74,9 @@ gNBs = initialDLBWPk0_3 = 0; initialDLBWPmappingType_3 = 0; - #this is SS=1,L=5 + #this is SS=1,L=4 initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -88,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 13475; + initialULBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -125,21 +126,26 @@ gNBs = # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # msg1_SubcarrierSpacing = 1, - # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 2; + initialULBWPk2_0 = 6; initialULBWPmappingType_0 = 1 # this is SS=0 L=11 initialULBWPstartSymbolAndLength_0 = 55; - initialULBWPk2_1 = 2; + initialULBWPk2_1 = 6; initialULBWPmappingType_1 = 1; # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -242,6 +248,8 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; sdr_addrs = "type=x300"; clock_src = "external"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc_b38_if5_ENDC.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc_b38_if5_ENDC.conf new file mode 100644 index 0000000000..9b611b3f07 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc_b38_if5_ENDC.conf @@ -0,0 +1,243 @@ +Active_eNBs = ( "eNB_Eurecom_VCO_B38"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_VCO_B38"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 222; mnc = 01; mnc_length = 2; } ); + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2585000000L; + uplink_frequency_offset = 0; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 5; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = 10; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -106; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + ue_TransmissionMode = 1; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.18.150"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; + t_dc_overall = 2000; + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "bond0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.203/24"; + ENB_INTERFACE_NAME_FOR_S1U = "bond0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.18.203/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.18.203/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="debug"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + puSch10xSnr = 100; + puCch10xSnr = 100; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 150; + } +); + +RUs = ( + { + local_if_name = "bond0"; + remote_address = "192.168.18.222"; + local_address = "192.168.18.203"; + local_portc = 50000; + remote_portc = 55444; + local_portd = 52001; + remote_portd = 52183; + local_rf = "no" + tr_preference = "udp_ecpri_if5" + nb_tx = 1 + nb_rx = 1 + att_tx = 5 + att_rx = 0; + eNB_instances = [0]; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf new file mode 100644 index 0000000000..1e32905733 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_eNB_band13.conf @@ -0,0 +1,285 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + ////////// Identification parameters: + eNB_ID = 0xe01; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( + { mcc = 311; mnc = 480; mnc_length = 3; } + ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + nb_antenna_ports = 1; + ue_TransmissionMode = 1; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 13; + downlink_frequency = 751000000L; + uplink_frequency_offset = 31000000; + Nid_cell = 0; + N_RB_DL = 25; //100; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + prach_root = 0; + tx_gain = 90; + rx_gain = 115; + pbch_repetition = "FALSE"; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -26; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; +/* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; +*/ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + //SSB central frequency of NR secondary cell group (for ENDC NSA) + nr_scg_ssb_freq = 2071241; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + enable_measurement_reports = "yes"; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.18.99"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.199/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.18.199/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.18.199/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="debug"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } +); + +THREAD_STRUCT = ( + { + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + worker_config = "ENABLE"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -26; + max_rxgain = 130; + eNB_instances = [0]; + clock_src = "external"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index fd1b62fd3d..555af5835d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -249,6 +249,7 @@ L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; + pusch_proc_threads = 8; } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf new file mode 100644 index 0000000000..108cf06033 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -0,0 +1,316 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({mcc = 222; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 518670; + dl_frequencyBand = 41; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 514854; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_0 = 53; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=10 + initialDLBWPstartSymbolAndLength_1 = 81; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 95; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=2,L=7 + initialDLBWPstartSymbolAndLength_3 = 86; + + initialDLBWPk0_4 = 0; + initialDLBWPmappingType_4 = 0; + #this is SS=2,L=5 + initialDLBWPstartSymbolAndLength_4 = 58; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 41; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "CI_FR1_CTL_ENB_IP_ADDR"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "CI_GNB_IP_ADDR"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf new file mode 100644 index 0000000000..4373f38e7b --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -0,0 +1,316 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({mcc = 222; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; # 6366 12925 12956 28875 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_0 = 53; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=10 + initialDLBWPstartSymbolAndLength_1 = 81; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 95; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=2,L=7 + initialDLBWPstartSymbolAndLength_3 = 86; + + initialDLBWPk0_4 = 0; + initialDLBWPmappingType_4 = 0; + #this is SS=2,L=5 + initialDLBWPstartSymbolAndLength_4 = 58; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "CI_FR1_CTL_ENB_IP_ADDR"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "CI_GNB_IP_ADDR"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 147bc955ae..5316705809 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -461,10 +461,9 @@ void eNB_top(PHY_VARS_eNB *eNB, L1_proc->subframe_rx = ru_proc->tti_rx; L1_proc->frame_tx = (L1_proc->subframe_rx > (9-sf_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx; L1_proc->subframe_tx = (L1_proc->subframe_rx + sf_ahead)%10; - + if (rxtx(eNB,L1_proc,string) < 0) - LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); - + LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); ru_proc->timestamp_tx = L1_proc->timestamp_tx; ru_proc->tti_tx = L1_proc->subframe_tx; ru_proc->frame_tx = L1_proc->frame_tx; @@ -1168,6 +1167,7 @@ void init_eNB_afterRU(void) { for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) { eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; + AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL, "RU %d : common.rxdataF is NULL\n", eNB->RU_list[ru_id]->idx); @@ -1177,7 +1177,7 @@ void init_eNB_afterRU(void) { for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i]; for (int ce_level=0; ce_level<4; ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; @@ -1239,7 +1239,8 @@ void init_eNB(int single_thread_flag, if (RC.eNB[inst] == NULL) RC.eNB[inst] = (PHY_VARS_eNB **) malloc(RC.nb_CC[inst]*sizeof(PHY_VARS_eNB *)); for (CC_id=0; CC_idabstraction_flag = 0; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index e3b9797105..56c2cb23dd 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -120,6 +120,8 @@ void configure_rru(int idx, void reset_proc(RU_t *ru); int connect_rau(RU_t *ru); +void wait_eNBs(void); + const char ru_states[6][9] = {"RU_IDLE","RU_CONFIG","RU_READY","RU_RUN","RU_ERROR","RU_SYNC"}; extern uint16_t sf_ahead; @@ -141,16 +143,12 @@ extern uint16_t sf_ahead; static inline void fh_if5_south_out(RU_t *ru,int frame, int subframe, 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 ); + ru->south_out_cnt++; + send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_RRH_GW_DL); } -// southbound IF5 fronthaul for Mobipass packet format -static inline void fh_if5_mobipass_south_out(RU_t *ru,int frame, int subframe, 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 ); - - send_IF5(ru, timestamp, subframe, &ru->seqno, IF5_MOBIPASS); -} // southbound IF4p5 fronthaul @@ -189,11 +187,12 @@ void fh_if5_south_in(RU_t *ru, recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; proc->tti_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - + if (proc->first_rx == 0) { if (proc->tti_rx != *subframe) { - LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d)\n",proc->tti_rx,*subframe); - exit_fun("Exiting"); + LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->tti_rx %d, subframe %d), resynching\n",proc->tti_rx,*subframe); + *frame=proc->frame_rx; + *subframe=proc->tti_rx; } if (proc->frame_rx != *frame) { @@ -324,48 +323,6 @@ void fh_slave_south_in(RU_t *ru, } -// asynchronous inbound if5 fronthaul from south (Mobipass) -void fh_if5_south_asynch_in_mobipass(RU_t *ru, - int *frame, - int *subframe) { - RU_proc_t *proc = &ru->proc; - LTE_DL_FRAME_PARMS *fp = ru->frame_parms; - recv_IF5(ru, &proc->timestamp_rx, *subframe, IF5_MOBIPASS); - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - int offset_mobipass = 40120; - pthread_mutex_lock(&proc->mutex_asynch_rxtx); - proc->tti_rx = ((proc->timestamp_rx-offset_mobipass)/fp->samples_per_tti)%10; - proc->frame_rx = ((proc->timestamp_rx-offset_mobipass)/(fp->samples_per_tti*10))&1023; - proc->tti_rx = (proc->timestamp_rx/fp->samples_per_tti)%10; - proc->frame_rx = (proc->timestamp_rx/(10*fp->samples_per_tti))&1023; - - if (proc->first_rx == 1) { - proc->first_rx =2; - *subframe = proc->tti_rx; - *frame = proc->frame_rx; - LOG_E(PHY,"[Mobipass]timestamp_rx:%llu, frame_rx %d, subframe: %d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,proc->tti_rx); - } else { - if (proc->tti_rx != *subframe) { - proc->first_rx++; - LOG_E(PHY,"[Mobipass]timestamp:%llu, tti_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx, proc->tti_rx,*subframe, proc->first_rx); - //exit_fun("Exiting"); - } - - if (proc->frame_rx != *frame) { - proc->first_rx++; - LOG_E(PHY,"[Mobipass]timestamp:%llu, frame_rx %d is not what we expect %d, first_rx:%d\n",(unsigned long long int)proc->timestamp_rx,proc->frame_rx,*frame, proc->first_rx); - // exit_fun("Exiting"); - } - - // temporary solution - *subframe = proc->tti_rx; - *frame = proc->frame_rx; - } - - pthread_mutex_unlock(&proc->mutex_asynch_rxtx); -} // eNodeB_3GPP_BBU - - // asynchronous inbound if4p5 fronthaul from south void fh_if4p5_south_asynch_in(RU_t *ru, int *frame, @@ -456,7 +413,7 @@ void fh_if5_north_asynch_in(RU_t *ru, int tti_tx,frame_tx; openair0_timestamp timestamp_tx; recv_IF5(ru, ×tamp_tx, *subframe, IF5_RRH_GW_DL); - // printf("Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); + // LOG_I(PHY,"Received subframe %d (TS %llu) from RCC\n",tti_tx,timestamp_tx); tti_tx = (timestamp_tx/fp->samples_per_tti)%10; frame_tx = (timestamp_tx/(fp->samples_per_tti*10))&1023; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx ); @@ -696,7 +653,7 @@ void rx_rf(RU_t *ru, ru->ts_offset = proc->timestamp_rx; proc->timestamp_rx = 0; } else if (resynch==0 && (proc->timestamp_rx - old_ts != fp->samples_per_tti)) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); + LOG_D(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,ru->ts_offset); ru->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); proc->timestamp_rx = ts-ru->ts_offset; } @@ -761,7 +718,7 @@ void rx_rf(RU_t *ru, *subframe = proc->tti_rx; } - //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe); + //LOG_I(PHY,"timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",ru->timestamp_rx,proc->frame_rx,frame,proc->tti_rx,subframe); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); if (rxs != fp->samples_per_tti) { @@ -929,12 +886,8 @@ static void *ru_thread_asynch_rxtx( void *param ) { LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n"); - // asynchronous receive from south (Mobipass) - if (ru->fh_south_asynch_in) { - ru->fh_south_asynch_in(ru, &frame, &subframe); - } // asynchronous receive from north (RRU IF4/IF5) - else if (ru->fh_north_asynch_in) { + if (ru->fh_north_asynch_in) { if (subframe_select(ru->frame_parms,subframe)!=SF_UL) ru->fh_north_asynch_in(ru, &frame, &subframe); } else @@ -1185,21 +1138,22 @@ void wakeup_L1s(RU_t *ru) { L1_proc_t *proc = &eNB->proc; struct timespec t; LOG_D(PHY, "wakeup_L1s (num %d) for RU %d (%d.%d) ru->eNB_top:%p\n", ru->num_eNB, ru->idx, ru->proc.frame_rx, ru->proc.tti_rx, ru->eNB_top); - // call eNB function directly char string[20]; sprintf(string, "Incoming RU %d", ru->idx); + + // call eNB function directly VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx); AssertFatal(0==pthread_mutex_lock(&proc->mutex_RU),""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 1); - //printf("wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n", - // ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,ru->wait_cnt,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx]); + //LOG_I(PHY,"wakeup_L1s: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask[%d] %x\n", + // ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,ru->wait_cnt,ru->proc.tti_rx,proc->RU_mask[ru->proc.tti_rx]); //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx); - //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx); + //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx); clock_gettime(CLOCK_MONOTONIC, &ru->proc.t[ru->proc.tti_rx]); if (proc->RU_mask[ru->proc.tti_rx] == 0) { - //clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.subframe_rx]); + //clock_gettime(CLOCK_MONOTONIC,&proc->t[ru->proc.tti_rx]); proc->t[ru->proc.tti_rx] = ru->proc.t[ru->proc.tti_rx]; //start_meas(&proc->ru_arrival_time); LOG_D(PHY,"RU %d starting timer for frame %d subframe %d\n", ru->idx, ru->proc.frame_rx, ru->proc.tti_rx); @@ -1212,13 +1166,13 @@ void wakeup_L1s(RU_t *ru) { eNB->RU_list[i]->idx, eNB->RU_list[i]->proc.frame_rx, eNB->RU_list[i]->proc.tti_rx, ru_states[eNB->RU_list[i]->state]); if (ru == eNB->RU_list[i] && eNB->RU_list[i]->wait_cnt == 0) { - //AssertFatal((proc->RU_mask&(1<Mod_id,ru->proc.frame_rx,ru->proc.subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask); + //AssertFatal((proc->RU_mask&(1<Mod_id,ru->proc.frame_rx,ru->proc.tti_rx,ru->idx,eNB->num_RU,proc->RU_mask); proc->RU_mask[ru->proc.tti_rx] |= (1<RU_list[i]->state == RU_SYNC ||*/(eNB->RU_list[i]->is_slave==1 && eNB->RU_list[i]->wait_cnt>0 && ru!=eNB->RU_list[i] && ru->is_slave==0) ) { proc->RU_mask[ru->proc.tti_rx] |= (1<cnt %d, i->cnt %d\n",ru->idx,ru->proc.subframe_rx,proc->RU_mask[ru->proc.subframe_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt); + //LOG_I(PHY,"RU %d, RU_mask[%d] %d, i %d, frame %d, slave %d, ru->cnt %d, i->cnt %d\n",ru->idx,ru->proc.tti_rx,proc->RU_mask[ru->proc.tti_rx],i,ru->proc.frame_rx,ru->is_slave,ru->wait_cnt,eNB->RU_list[i]->wait_cnt); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.tti_rx]); if (ru->is_slave == 0 && ( (proc->RU_mask[ru->proc.tti_rx]&(1<RU_list[i]->state == RU_RUN) { //This is master & the RRU has already been received @@ -1233,21 +1187,21 @@ void wakeup_L1s(RU_t *ru) { } //clock_gettime(CLOCK_MONOTONIC,&t); - //LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.subframe_rx], t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec); + //LOG_I(PHY,"RU mask is now %x, time is %lu\n",proc->RU_mask[ru->proc.tti_rx], t.tv_nsec - proc->t[ru->proc.tti_rx].tv_nsec); if (proc->RU_mask[ru->proc.tti_rx] == (1<num_RU)-1) { // all RUs have provided their information so continue on and wakeup eNB top LOG_D(PHY,"ru_mask is %d \n ", proc->RU_mask[ru->proc.tti_rx]); LOG_D(PHY,"the number of RU is %d, the current ru is RU %d \n ", (1<num_RU)-1, ru->idx); - LOG_D(PHY,"ru->proc.subframe_rx is %d \n", ru->proc.tti_rx); + LOG_D(PHY,"ru->proc.tti_rx is %d \n", ru->proc.tti_rx); LOG_D(PHY,"Resetting mask frame %d, subframe %d, this is RU %d\n", ru->proc.frame_rx, ru->proc.tti_rx, ru->idx); proc->RU_mask[ru->proc.tti_rx] = 0; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_MASK_RU, proc->RU_mask[ru->proc.tti_rx]); clock_gettime(CLOCK_MONOTONIC,&t); //stop_meas(&proc->ru_arrival_time); - /*AssertFatal(t.tv_nsec < proc->t[ru->proc.subframe_rx].tv_nsec+5000000, "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n", - ru->proc.subframe_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.subframe_rx].tv_nsec, ru->idx);*/ + /*AssertFatal(t.tv_nsec < proc->t[ru->proc.tti_rx].tv_nsec+5000000, "Time difference for subframe %d (Frame %d) => %lu > 5ms, this is RU %d\n", + ru->proc.tti_rx, ru->proc.frame_rx, t.tv_nsec - proc->t[ru->proc.tti_rx].tv_nsec, ru->idx);*/ //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.frame_rx); - //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.subframe_rx); + //VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_WAKEUP_L1S_RU+ru->idx, ru->proc.tti_rx); AssertFatal(0==pthread_mutex_unlock(&proc->mutex_RU),""); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_LOCK_MUTEX_RU+ru->idx, 0 ); // unlock RUs that are waiting for eNB processing to be completed @@ -1280,8 +1234,8 @@ void wakeup_L1s(RU_t *ru) { } // pthread_mutex_unlock(&proc->mutex_RU); - // LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.subframe_rx); - // ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.subframe_rx,string); + // LOG_D(PHY,"wakeup eNB top for for subframe %d\n", ru->proc.tti_rx); + // ru->eNB_top(eNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string); ru->proc.emulate_rf_busy = 0; } @@ -1350,7 +1304,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { LTE_DL_FRAME_PARMS *fp = ru->frame_parms; openair0_config_t *cfg = &ru->openair0_cfg; - //printf("////////////////numerology in config = %d\n",numerology); + //LOG_I(PHY,"////////////////numerology in config = %d\n",numerology); int numerology = get_softmodem_params()->numerology; if(fp->N_RB_DL == 100) { @@ -1377,7 +1331,7 @@ void fill_rf_config(RU_t *ru, cfg->tx_bw = 40e6; cfg->rx_bw = 40e6; } else { - printf("Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology); + LOG_I(PHY,"Wrong input for numerology %d\n setting to 20MHz normal CP configuration",numerology); cfg->sample_rate=30.72e6; cfg->samples_per_frame = 307200; cfg->tx_bw = 10e6; @@ -1416,7 +1370,7 @@ void fill_rf_config(RU_t *ru, cfg->tx_gain[i] = (double)ru->att_tx; cfg->rx_gain[i] = ru->max_rxgain-(double)ru->att_rx; cfg->configFilename = rf_config_file; - printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", + LOG_I(PHY,"channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", i, cfg->tx_gain[i], cfg->rx_gain[i], cfg->tx_freq[i], @@ -1437,9 +1391,9 @@ int setup_RU_buffers(RU_t *ru) { if (ru) { frame_parms = ru->frame_parms; - printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); + LOG_I(PHY,"setup_RU_buffers: frame_parms = %p\n",frame_parms); } else { - printf("RU not initialized (NULL pointer)\n"); + LOG_I(PHY,"RU not initialized (NULL pointer)\n"); return(-1); } @@ -1462,7 +1416,7 @@ int setup_RU_buffers(RU_t *ru) { ru->sf_extension /= 4; ru->end_of_burst_delay /= 4; } else { - printf("not handled, todo\n"); + LOG_I(PHY,"not handled, todo\n"); exit(1); } } else { @@ -1476,13 +1430,13 @@ int setup_RU_buffers(RU_t *ru) { for (i=0; inb_rx; i++) { card = i/4; ant = i%4; - printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + LOG_I(PHY,"Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); free(ru->common.rxdata[i]); ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; - printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); + LOG_I(PHY,"rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); for (j=0; j<16; j++) { - printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); + LOG_I(PHY,"rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); ru->common.rxdata[i][j] = 16-j; } } @@ -1490,13 +1444,13 @@ int setup_RU_buffers(RU_t *ru) { for (i=0; inb_tx; i++) { card = i/4; ant = i%4; - printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); + LOG_I(PHY,"Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); free(ru->common.txdata[i]); ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; - printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); + LOG_I(PHY,"txdata[%d] @ %p\n",i,ru->common.txdata[i]); for (j=0; j<16; j++) { - printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); + LOG_I(PHY,"txbuffer %d: %x\n",j,ru->common.txdata[i][j]); ru->common.txdata[i][j] = 16-j; } } @@ -1623,7 +1577,7 @@ static void *ru_thread_tx( void *param ) { } if (eNB_proc->RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - //printf("Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU); + //LOG_I(PHY,"Not all RUs have provided their info (mask = %d), RU %d, num_RUs %d\n", eNB_proc->RU_mask_tx,ru->idx,eNB->num_RU); AssertFatal((ret=pthread_mutex_unlock(&eNB_proc->mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); } else { // all RUs TX are finished so send the ready signal to eNB processing eNB_proc->RU_mask_tx = 0; @@ -1644,7 +1598,7 @@ static void *ru_thread_tx( void *param ) { } } - //printf("ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n", + //LOG_I(PHY,"ru_thread_tx: Frame %d, Subframe %d: RU %d done (wait_cnt %d),RU_mask_tx %d\n", //eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,ru->wait_cnt,eNB_proc->RU_mask_tx); } @@ -1676,12 +1630,10 @@ static void *ru_thread( void *param ) { LOG_I(PHY,"Starting RU %d (%s,%s),\n", ru->idx, NB_functions[ru->function], NB_timing[ru->if_timing]); if(get_softmodem_params()->emulate_rf) { - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(ru->frame_parms,1); phy_init_RU(ru); if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); + LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n"); exit(-1); } @@ -1693,24 +1645,20 @@ static void *ru_thread( void *param ) { ru->state = RU_RUN; } else if (ru->has_ctrl_prt == 0) { // There is no control port: start everything here - LOG_I(PHY, "RU %d has not ctrl port\n",ru->idx); + LOG_I(PHY, "RU %d has no OAI ctrl port\n",ru->idx); - if (ru->if_south == LOCAL_RF) { - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(ru->frame_parms,1); - ru->frame_parms->nb_antennas_rx = ru->nb_rx; - phy_init_RU(ru); - openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + fill_rf_config(ru,ru->rf_config_file); + init_frame_parms(ru->frame_parms,1); + ru->frame_parms->nb_antennas_rx = ru->nb_rx; - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - } + if (ru->if_south == LOCAL_RF) openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret); - RC.ru_mask &= ~(1<idx); - pthread_cond_signal(&RC.ru_cond); - AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret); + phy_init_RU(ru); + + + if (setup_RU_buffers(ru)!=0) { + LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n"); + exit(-1); } AssertFatal((ret=pthread_mutex_lock(&RC.ru_mutex))==0,"mutex_lock returns %d\n",ret); @@ -1745,9 +1693,9 @@ static void *ru_thread( void *param ) { // Start RF device if any if (ru->start_rf) { - if (ru->start_rf(ru) != 0) - LOG_E(HW,"Could not start the RF device\n"); - else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); + if (ru->start_rf(ru) != 0) + AssertFatal(1==0,"Could not start the RF device\n"); + else LOG_I(PHY,"RU %d rf device ready\n",ru->idx); } else LOG_D(PHY,"RU %d no rf device\n",ru->idx); } @@ -1781,7 +1729,6 @@ static void *ru_thread( void *param ) { // synchronization on input FH interface, acquire signals/data and block if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe); else AssertFatal(1==0, "No fronthaul interface at south port"); - #ifdef PHY_TX_THREAD if(first_phy_tx == 0) { @@ -1945,7 +1892,7 @@ static void *ru_thread( void *param ) { } // ru->state = RU_RUN } // while !oai_exit - printf( "Exiting ru_thread \n"); + LOG_I(PHY, "Exiting ru_thread \n"); if (!(get_softmodem_params()->emulate_rf)) { if (ru->stop_rf != NULL) { @@ -2017,6 +1964,7 @@ void *ru_thread_synch(void *arg) { #if defined(PRE_SCD_THREAD) void *pre_scd_thread( void *param ) { + void rlc_tick(int, int); static int eNB_pre_scd_status; protocol_ctxt_t ctxt; int frame; @@ -2051,6 +1999,7 @@ void *pre_scd_thread( void *param ) { AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_pre_scd))==0,"mutex_unlock returns %d\n",ret); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES, NOT_A_RNTI, frame, subframe,Mod_id); + rlc_tick(frame, subframe); pdcp_run(&ctxt); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -2188,6 +2137,12 @@ static void *rf_tx( void *param ) { #endif + +int start_streaming(RU_t *ru) { + LOG_I(PHY,"Starting streaming on third-party RRU\n"); + return(ru->ifdevice.thirdparty_startstreaming(&ru->ifdevice)); +} + int start_if(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB) { return(ru->ifdevice.trx_start_func(&ru->ifdevice)); } @@ -2233,7 +2188,7 @@ void reset_proc(RU_t *ru) { void init_RU_proc(RU_t *ru) { - int i=0, ret; + int i=0; RU_proc_t *proc; pthread_attr_t *attr_FH=NULL, *attr_FH1=NULL, *attr_prach=NULL, *attr_asynch=NULL, *attr_synch=NULL, *attr_emulateRF=NULL, *attr_ctrl=NULL, *attr_prach_br=NULL; //pthread_attr_t *attr_fep=NULL; @@ -2302,7 +2257,17 @@ void init_RU_proc(RU_t *ru) { attr_prach_br = &proc->attr_prach_br; #endif - if (ru->function!=eNodeB_3GPP) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void *)ru ); + if (ru->has_ctrl_prt == 1) pthread_create( &proc->pthread_ctrl, attr_ctrl, ru_thread_control, (void*)ru ); + else { + if (ru->start_if) { + LOG_I(PHY,"Starting IF interface for RU %d\n",ru->idx); + AssertFatal( + ru->start_if(ru,NULL) == 0, "Could not start the IF device\n"); + + if (ru->if_south != LOCAL_RF) wait_eNBs(); + } + } + pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void *)ru ); #if defined(PRE_SCD_THREAD) @@ -2341,23 +2306,6 @@ void init_RU_proc(RU_t *ru) { LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__); pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void *)ru ); ru->state=RU_RUN; - if(!get_softmodem_params()->emulate_rf) - { - fill_rf_config(ru,ru->rf_config_file); - init_frame_parms(ru->frame_parms,1); - ru->frame_parms->nb_antennas_rx = ru->nb_rx; - phy_init_RU(ru); - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (ret < 0) { - LOG_I(PHY,"Exiting, cannot load device. Make sure that your SDR board is connected!\n"); - exit(1); - } - - if (setup_RU_buffers(ru)!=0) { - LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n"); - exit(1); - } - } } if (get_thread_worker_conf() == WORKER_ENABLE) { @@ -2366,7 +2314,7 @@ void init_RU_proc(RU_t *ru) { } if (opp_enabled == 1) pthread_create(&ru->ru_stats_thread,NULL,ru_stats_thread,(void *)ru); - +/* if (ru->function == eNodeB_3GPP) { usleep(10000); LOG_I(PHY, "Signaling main thread that RU %d (is_slave %d,send_dmrs %d) is ready in state %s\n",ru->idx,ru->is_slave,ru->generate_dmrs_sync,ru_states[ru->state]); @@ -2375,6 +2323,7 @@ void init_RU_proc(RU_t *ru) { pthread_cond_signal(&RC.ru_cond); AssertFatal((ret=pthread_mutex_unlock(&RC.ru_mutex))==0,"mutex_unlock returns %d\n",ret); } + */ } @@ -2537,6 +2486,7 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) { void set_function_spec_param(RU_t *ru) { int ret; + switch (ru->if_south) { case LOCAL_RF: // this is an RU with integrated RF (RRU, eNB) if (ru->function == NGFI_RRU_IF5) { // IF5 RRU @@ -2557,10 +2507,10 @@ void set_function_spec_param(RU_t *ru) { reset_meas(&ru->compression); reset_meas(&ru->transport); ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + LOG_I(PHY,"NGFI_RRU_IF5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); + LOG_I(PHY,"Exiting, cannot initialize transport protocol\n"); exit(-1); } } else if (ru->function == NGFI_RRU_IF4p5) { @@ -2581,10 +2531,10 @@ void set_function_spec_param(RU_t *ru) { reset_meas(&ru->compression); reset_meas(&ru->transport); ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + LOG_I(PHY,"NGFI_RRU_if4p5 : openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); + LOG_I(PHY,"Exiting, cannot initialize transport protocol\n"); exit(-1); } @@ -2604,7 +2554,7 @@ void set_function_spec_param(RU_t *ru) { ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface ru->stop_rf = stop_rf; - printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); + LOG_I(PHY,"NFGI_RRU_IF4p5: configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); /* if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise fill_rf_config(ru,rf_config_file); @@ -2614,7 +2564,7 @@ void set_function_spec_param(RU_t *ru) { ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); + LOG_I(PHY,"Exiting, cannot initialize RU Buffers\n"); exit(-1); }*/ break; @@ -2627,25 +2577,22 @@ void set_function_spec_param(RU_t *ru) { if (ru->if_timing == synch_to_other) { ru->fh_south_in = fh_slave_south_in; // synchronize to master - ru->fh_south_out = fh_if5_mobipass_south_out; // use send_IF5 for mobipass - ru->fh_south_asynch_in = fh_if5_south_asynch_in_mobipass; // UL is asynchronous } else { 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->start_rf = ru->eth_params.transp_preference == ETH_UDP_IF5_ECPRI_MODE ? start_streaming : NULL; ru->stop_rf = NULL; ru->start_if = start_if; // need to start if interface for IF5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; ru->ifdevice.configure_rru = configure_ru; ret = openair0_transport_load(&ru->ifdevice,&ru->openair0_cfg,&ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + LOG_I(PHY,"REMOTE_IF5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); + LOG_I(PHY,"Exiting, cannot initialize transport protocol\n"); exit(-1); } @@ -2668,10 +2615,10 @@ void set_function_spec_param(RU_t *ru) { ru->ifdevice.eth_params = &ru->eth_params; ru->ifdevice.configure_rru = configure_ru; ret = openair0_transport_load(&ru->ifdevice, &ru->openair0_cfg, &ru->eth_params); - printf("openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); + LOG_I(PHY,"REMOTE IF4p5: openair0_transport_init returns %d for ru_id %d\n", ret, ru->idx); if (ret<0) { - printf("Exiting, cannot initialize transport protocol\n"); + LOG_I(PHY,"Exiting, cannot initialize transport protocol\n"); exit(-1); } @@ -2685,12 +2632,14 @@ void set_function_spec_param(RU_t *ru) { } malloc_IF4p5_buffer(ru); + break; default: LOG_E(PHY,"RU with invalid or unknown southbound interface type %d\n",ru->if_south); break; } // switch on interface type + } //extern void RCconfig_RU(void); @@ -2780,6 +2729,11 @@ void init_RU(char *rf_config_file, int send_dmrssync) { LOG_I(PHY, "Initializing RRU descriptor %d : (%s,%s,%d)\n", ru_id, ru_if_types[ru->if_south], NB_timing[ru->if_timing], ru->function); set_function_spec_param(ru); + if (ru->function != NGFI_RRU_IF4p5 && ru->function != NGFI_RRU_IF5) { + fill_rf_config(ru,ru->rf_config_file); + init_frame_parms(ru->frame_parms,1); + } + LOG_I(PHY, "Starting ru_thread %d, is_slave %d, send_dmrs %d\n", ru_id, ru->is_slave, ru->generate_dmrs_sync); init_RU_proc(ru); } // for ru_id @@ -2793,7 +2747,7 @@ void stop_ru(RU_t *ru) { #if defined(PRE_SCD_THREAD) || defined(PHY_TX_THREAD) int *status; #endif - printf("Stopping RU %p processing threads\n",(void *)ru); + LOG_I(PHY,"Stopping RU %p processing threads\n",(void *)ru); #if defined(PRE_SCD_THREAD) if(ru) { @@ -2847,7 +2801,7 @@ void init_ru_vnf(void) { pthread_mutex_init(&RC.ru_mutex,NULL); pthread_cond_init(&RC.ru_cond,NULL); // read in configuration file) - printf("configuring RU from file\n"); + LOG_I(PHY,"configuring RU from file\n"); RCconfig_RU(); LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs()); @@ -2937,7 +2891,7 @@ void RCconfig_RU(void) { RC.ru[j] = (RU_t *)malloc(sizeof(RU_t)); memset((void *)RC.ru[j],0,sizeof(RU_t)); RC.ru[j]->idx = j; - printf("Creating RC.ru[%d]:%p\n", j, RC.ru[j]); + LOG_I(PHY,"Creating RC.ru[%d]:%p\n", j, RC.ru[j]); RC.ru[j]->if_timing = synch_to_ext_device; if (RC.nb_L1_inst >0) @@ -2947,7 +2901,7 @@ void RCconfig_RU(void) { for (i=0; inum_eNB; i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; - RC.ru[j]->has_ctrl_prt = 1; + RC.ru[j]->has_ctrl_prt = 0; if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); @@ -2994,7 +2948,7 @@ void RCconfig_RU(void) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = eNodeB_3GPP; RC.ru[j]->state = RU_RUN; - printf("Setting function for RU %d to eNodeB_3GPP\n",j); + LOG_I(PHY,"Setting function for RU %d to eNodeB_3GPP\n",j); } else { RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); @@ -3004,42 +2958,43 @@ void RCconfig_RU(void) { // Check if control port set if (!(config_isparamset(RUParamList.paramarray[j],RU_REMOTE_PORTC_IDX)) ) { - printf("Removing control port for RU %d\n",j); + LOG_I(PHY,"Removing control port for RU %d\n",j); RC.ru[j]->has_ctrl_prt = 0; } else { RC.ru[j]->eth_params.my_portc = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr); RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); - printf(" Control port %u \n",RC.ru[j]->eth_params.my_portc); + LOG_I(PHY," Control port %u \n",RC.ru[j]->eth_params.my_portc); } if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF5; RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); + LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j); } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); + LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j); } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); + RC.ru[j]->has_ctrl_prt =1; + LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j); } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { RC.ru[j]->if_south = LOCAL_RF; RC.ru[j]->function = NGFI_RRU_IF4p5; RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); + LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j); } - printf("RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr)); + LOG_I(PHY,"RU %d is_slave=%s\n",j,*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr)); if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; else RC.ru[j]->is_slave=0; - printf("RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr)); + LOG_I(PHY,"RU %d ota_sync_enabled=%s\n",j,*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr)); if (strcmp(*(RUParamList.paramarray[j][RU_OTA_SYNC_ENABLE_IDX].strptr), "yes") == 0) RC.ru[j]->ota_sync_enable=1; else RC.ru[j]->ota_sync_enable=0; @@ -3053,8 +3008,8 @@ void RCconfig_RU(void) { for (i=0; inum_bands; i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; } //strcmp(local_rf, "yes") == 0 - else { - printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); +else { + LOG_I(PHY,"RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr)); RC.ru[j]->eth_params.local_if_name = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr)); RC.ru[j]->eth_params.my_addr = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); RC.ru[j]->eth_params.remote_addr = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr)); @@ -3062,34 +3017,34 @@ void RCconfig_RU(void) { RC.ru[j]->eth_params.remote_portc = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr); RC.ru[j]->eth_params.my_portd = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr); RC.ru[j]->eth_params.remote_portd = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr); - + if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE; + } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_ecpri_if5") == 0) { + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF5_ECPRI_MODE; } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; + RC.ru[j]->if_south = REMOTE_IF5; + RC.ru[j]->function = NGFI_RAU_IF5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE; } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE; + RC.ru[j]->has_ctrl_prt = 1; } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) { - RC.ru[j]->if_south = REMOTE_IF4p5; - RC.ru[j]->function = NGFI_RAU_IF4p5; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; - } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) { - RC.ru[j]->if_south = REMOTE_IF5; - RC.ru[j]->function = NGFI_RAU_IF5; - RC.ru[j]->if_timing = synch_to_other; - RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS; + RC.ru[j]->if_south = REMOTE_IF4p5; + RC.ru[j]->function = NGFI_RAU_IF4p5; + RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE; + + if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; + else RC.ru[j]->is_slave=0; } - - if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1; - else RC.ru[j]->is_slave=0; } /* strcmp(local_rf, "yes") != 0 */ - + RC.ru[j]->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); 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); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 0d0dde4ac4..a602e762f1 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -386,7 +386,7 @@ void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { LOG_I(ENB_APP, "sending TERMINATE_MESSAGE from task %s (%d) to task %s (%d)\n", itti_get_task_name(from), from, itti_get_task_name(to), to); MessageDef *msg; - msg = itti_alloc_new_message (from, TERMINATE_MESSAGE); + msg = itti_alloc_new_message (from, 0, TERMINATE_MESSAGE); itti_send_msg_to_task (to, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } @@ -453,7 +453,7 @@ int restart_L1L2(module_id_t enb_id) { /* pass a reconfiguration request which will configure everything down to * RC.eNB[i][j]->frame_parms, too */ - msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); + msg_p = itti_alloc_new_message(TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); /* TODO XForms might need to be restarted, but it is currently (09/02/18) @@ -544,14 +544,14 @@ int main ( int argc, char **argv ) cpuf=get_cpu_freq_GHz(); printf("ITTI init, useMME: %i\n",EPC_MODE_ENABLED); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); // allows to forward in wireshark L2 protocol for decoding // initialize mscgen log after ITTI if (get_softmodem_params()->start_msc) { load_module_shlib("msc",NULL,0,&msc_interface); } - MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); + MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); init_opt(); // to make a graceful exit when ctrl-c is pressed set_softmodem_sighandler(); @@ -596,7 +596,7 @@ int main ( int argc, char **argv ) } for (int enb_id = 0; enb_id < RC.nb_inst; enb_id++) { - MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ); + MessageDef *msg_p = itti_alloc_new_message (TASK_ENB_APP, 0, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task (TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); } diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 0962bb6a2d..407756e20f 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -787,10 +787,10 @@ static void *UE_thread_rxn_txnp4(void *arg) if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 ) CPU_SET(threads.one, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 ) + if ( RX_NB_TH > 1 && (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 ) CPU_SET(threads.two, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) + if ( RX_NB_TH > 2 && (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 ) CPU_SET(threads.three, &cpuset); //CPU_SET(threads.three, &cpuset); @@ -1596,7 +1596,7 @@ void *UE_thread(void *arg) wait_sync("UE thread"); #ifdef NAS_UE MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_NAS_UE, UE->Mod_id + NB_eNB_INST, message_p); #endif int sub_frame=-1; @@ -1976,7 +1976,7 @@ void init_UE_single_thread_stub(int nb_inst) if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { #ifdef NAS_UE MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + message_p = itti_alloc_new_message(TASK_NAS_UE, 0, INITIALIZE_MESSAGE); itti_send_msg_to_task (TASK_NAS_UE, i + NB_eNB_INST, message_p); #endif } diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 54a9f4a669..9bf179efb9 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -95,9 +95,6 @@ pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -#ifdef UESIM_EXPANSION - uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; -#endif uint16_t sf_ahead=2; int tddflag; char *emul_iface; @@ -503,7 +500,7 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) { void terminate_task(task_id_t task_id, module_id_t mod_id) { LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); MessageDef *msg; - msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE); itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); } @@ -543,12 +540,15 @@ void init_pdcp(void) { pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); } +// Stupid function addition because UE itti messages queues definition is common with eNB +void *rrc_enb_process_msg(void *notUsed) { +AssertFatal(false,""); + return NULL; +} + int main( int argc, char **argv ) { int CC_id; uint8_t abstraction_flag=0; -#ifdef UESIM_EXPANSION - memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list)); -#endif // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues NB_UE_INST=1; @@ -601,14 +601,14 @@ int main( int argc, char **argv ) { pthread_mutex_init(&sync_mutex, NULL); printf("ITTI init\n"); - itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); + itti_init(TASK_MAX, tasks_info); // initialize mscgen log after ITTI if (get_softmodem_params()->start_msc) { load_module_shlib("msc",NULL,0,&msc_interface); } - MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); + MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); init_opt(); init_pdcp(); //TTN for D2D diff --git a/targets/RT/USER/rcc_if5.gtkw b/targets/RT/USER/rcc_if5.gtkw index d64a9ca0fb..34c6bab5d1 100644 --- a/targets/RT/USER/rcc_if5.gtkw +++ b/targets/RT/USER/rcc_if5.gtkw @@ -1,41 +1,67 @@ [*] -[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI -[*] Sun Jul 31 13:30:42 2016 +[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI +[*] Tue Sep 24 06:59:08 2019 [*] [dumpfile] "/tmp/openair_dump_eNB.vcd" -[dumpfile_mtime] "Sun Jul 31 13:21:59 2016" -[dumpfile_size] 18273240 -[savefile] "/home/fourmi/openairinterface5g/targets/RT/USER/rcc_if5.gtkw" -[timestart] 24070893000 -[size] 1301 716 -[pos] 309 0 -*-19.793451 29026062100 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -[sst_width] 284 -[signals_width] 262 +[dumpfile_mtime] "Mon Sep 23 20:04:56 2019" +[dumpfile_size] 1625759 +[savefile] "/home/orange/aw2s/openairinterface5g/targets/RT/USER/rcc_if5.gtkw" +[timestart] 12600104000 +[size] 1215 1000 +[pos] 0 22 +*-19.506693 12600920638 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[sst_width] 386 +[signals_width] 344 [sst_expanded] 1 -[sst_vpaned_height] 294 +[sst_vpaned_height] 303 +@29 +functions.send_if5 +@28 +functions.recv_if5 @24 variables.trx_ts[63:0] variables.trx_tst[63:0] @28 -functions.send_if5 -functions.recv_if5 functions.eNB_thread_rxtx0 @24 +variables.frame_number_RX0_RU[63:0] +variables.subframe_number_RX0_RU[63:0] +variables.frame_number_TX0_RU[63:0] +variables.subframe_number_TX0_RU[63:0] +@28 +functions.mac_schedule_dlsch +functions.macxface_eNB_dlsch_ulsch_scheduler +functions.macxface_ue_scheduler +functions.phy_eNB_ofdm_mod_l +@24 variables.frame_number_RX0_eNB[63:0] variables.subframe_number_RX0_eNB[63:0] variables.frame_number_TX0_eNB[63:0] variables.subframe_number_TX0_eNB[63:0] -@28 -functions.eNB_thread_rxtx1 -@24 variables.frame_number_RX1_eNB[63:0] variables.subframe_number_RX1_eNB[63:0] variables.frame_number_TX1_eNB[63:0] variables.subframe_number_TX1_eNB[63:0] @28 +functions.phy_eNB_dlsch_modulation +functions.phy_eNB_dlsch_encoding +functions.phy_eNB_dlsch_scrambling +functions.phy_eNB_beam_precoding +functions.phy_enb_pdcch_tx +functions.phy_enb_prach_rx +functions.phy_procedures_ru_feprx0 +functions.phy_procedures_eNb_rx_uespec0 +functions.phy_procedures_eNb_rx_uespec1 +functions.phy_enb_sfgen +functions.phy_procedures_eNb_tx0 +functions.phy_procedures_eNb_tx1 +functions.phy_procedures_ru_feprx1 +functions.phy_procedures_ru_feptx_ofdm0 +functions.phy_procedures_ru_feptx_ofdm1 +functions.phy_procedures_ru_feptx_prec0 +functions.phy_procedures_ru_feptx_prec1 +functions.eNB_thread_rxtx1 functions.phy_enb_sfgen -functions.phy_eNB_slot_fep functions.phy_enb_prach_rx @24 variables.dci_info[63:0] diff --git a/targets/RT/USER/ru_control.c b/targets/RT/USER/ru_control.c index 6daf0f4dfa..7ac6a8913e 100644 --- a/targets/RT/USER/ru_control.c +++ b/targets/RT/USER/ru_control.c @@ -524,7 +524,7 @@ void* ru_thread_control( void* param ) } - ru->state = (ru->function==eNodeB_3GPP)? RU_RUN : RU_IDLE; + ru->state = (ru->function==eNodeB_3GPP || ru->if_south == REMOTE_IF5)? RU_RUN : RU_IDLE; LOG_I(PHY,"Control channel ON for RU %d\n", ru->idx); while (!oai_exit) // Change the cond